在python中迭代utf-8字符

时间:2017-12-08 08:25:23

标签: python utf-8 character-encoding python-3.6

我使用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位字符。这样做的正确方法是什么?

提前致谢。

1 个答案:

答案 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。在分解形式中,实际上有两个(或更多)字符(每个字符可能用多个字节表示,具体取决于编码)。显示设备(终端模拟器,编辑器......)将其显示为带有基本字符上方/下方标记的单个字母。