我使用python 3.6以西班牙语读取以utf-8编码的文件(因此,包括字母ñ)。我使用utf-8编解码器打开文件,并正确加载:在调试时,我可以在加载的文本中看到ñ。
然而,当我迭代字符时,ñ被读作两个字符,n和〜。具体来说,当我跑:
for c in text:
hexc = int(hex(ord(c)), 16)
if U_LETTERS[lang][0] <= hexc <= U_LETTERS[lang][1] \
or hexc in U_LETTERS[lang][2:] \
or hexc == U_SPACE:
filtered_text+=c
和文本包含ñ,变量c将其视为n(因此,hexc为110而不是241),然后它需要〜(和hexc为771)。我想当以这种方式迭代时,内部转换为8位字符。这样做的正确方法是什么?
提前致谢。
答案 0 :(得分:5)
这与Unicode规范化有关。字母“ñ”可以用代码点0xF1(241)的单个字符表示,或者用两个字符“n”表示,也可以用叠加的代字号组合字符表示。代码点0x6E和0x0303(110和771)。
这两种表达信件的方式被视为等效;但是,它们在字符串比较中并不相同。
Python提供了通过unicodedata
模块从一种形式转换为另一种形式的功能。
第一种形式称为组成(NFC),第二种形式称为分解(NFD)标准化形式。
一个例子以最简单的方式解释:
>>> import unicodedata
>>> '\xf1'
'ñ'
>>> [ord(c) for c in '\xf1']
[241]
>>> [ord(c) for c in unicodedata.normalize('NFD', '\xf1')]
[110, 771]
>>> [ord(c) for c in unicodedata.normalize('NFC', 'n\u0303')]
[241]
>>>
因此,要解决您的问题,请在进一步处理之前将所有文本转换为所需的规范化表单。
注意:Unicode规范化是与编码分开的问题。您也可以使用UTF16或UTF32。在分解形式中,实际上有两个(或更多)字符(每个字符可能用多个字节表示,具体取决于编码)。显示设备(终端模拟器,编辑器......)将其显示为带有基本字符上方/下方标记的单个字母。