mongodb 单词相同但Unicode字符不同

z4bn682m  于 2022-11-03  发布在  Go
关注(0)|答案(2)|浏览(158)

我在Windows上用Python构建了一个关于越南餐馆的问答应用程序。要写越南字符,我需要使用Unicode。
首先,我从TripAdvisor网站上克隆数据,使用HTML charset=utf-8,并建立我的Mongo数据库。一个名为“a nng”的城市在TripAdvisor有一个代码:

>>> print repr("đà nẵng")     # from tripadvisor website 
>>> '\xc4\x91a\xcc\x80 n\xc4\x83\xcc\x83ng'

然而,当我在Firefox的地址栏中查询时,城市“a nng”有一个不同的代码:

>>> print repr("đà nẵng")   # Firefox's address bar
>>> '\xc4\x91\xc3\xa0 n\xe1\xba\xb5ng'

这就是为什么我在我的数据库中找不到这个城市的原因。我试着在记事本++上写这个城市的名字,得到了和使用火狐的地址栏一样的结果

>>> print repr("đà nẵng")   # notepad++ using 'Encoding UTF-8'
>>> '\xc4\x91\xc3\xa0 n\xe1\xba\xb5ng'

有没有办法在两种类型的代码之间进行转换?
或者在这种情况下,是否有任何方法可以将城市名称“à n angng”与不同的代码匹配?

km0tfn4u

km0tfn4u1#

你遇到的问题是,unicode允许多种方式组成同一个符号。Python模块unicodedata提供了一个函数normalize,允许你将unicode表示转换为固定的形式(例如NFC)。

from unicodedata import normalize

S1 = b'\xc4\x83\xcc\x83'.decode('UTF-8')
S2 = b'\xe1\xba\xb5'.decode('UTF-8')

print(normalize('NFC', S1).encode('UTF-8'))
print(normalize('NFC', S2).encode('UTF-8'))

在您的示例中,tripadvisor以NFD形式显示,而记事本使用NFC。

pzfprimi

pzfprimi2#

虽然这是一个老问题,但我会为任何偶然发现这个问题的人添加一个答案。
两个字节序列的区别在于规范等价。有些字符可以用多个字节序列来表示。对于字母Ø,5种可能的规范等价表示。在python中,可以使用pyicu来得到一个特定字符串的所有规范等价列表。
但是在这个问题的例子中,Firefox使用NFC表示nng,字节序列是b 'n\xe1\xba\xb5ng'。
但是到到网给出的字节序列是b 'n\xc4\x83\xcc\x83ng'。这不是NFC,也不是NFD。NFD的等价物是b 'na\xcc\x86\xcc\x83ng'。
Trip Advisor中的字符串是使用Window的越南语键盘输入的。当微软第一次实现越南语Unicode键盘时,他们遵循Windows-1252的字符模型,带有抑扬符、短音符或钩的元音是单个的预合成字符,所有的音调标记都由组合的变音符号表示,因此当时生成的文本是预合成和分解序列的混合。NFC或NFD都不是。
因此,在这个例子中,'nng'是:
第一个

相关问题