看起来相同但编码不同的字符串

时间:2017-01-20 12:07:00

标签: python python-2.7 unicode utf-8

我有两个文件:file1.csv和file2.csv,每个文件都在第一行和唯一一行写有名称“Aarão”。 file1.csv是从Google电子表格的“导出为”生成的;而file2.csv是由我手动创建的,使用nano。两个文件都以utf-8编码:

file -I file1.csv 
file1.csv: text/plain; charset=utf-8

file -I file2.csv 
file2.csv: text/plain; charset=utf-8
当我用nano打开它们时,两者看起来都是平等的,但实际上是不同的:

>>> with io.open('file1.csv','r',encoding = 'utf8') as f1:
...     for line in f1:
...             word1 = line 
... 
>>> word1
u'Aara\u0303o\n'
>>> 
>>> with io.open('file2.csv','r',encoding = 'utf8') as f2:
...     for line in f2:
...             word2 = line
... 
>>> word2
u'Aar\xe3o\n'

那么,我如何纠正这个问题,即将一个转换为另一个,以便我可以检查它们是否是同一个单词? (在python中)

3 个答案:

答案 0 :(得分:7)

正如deceze,Serge和Simon所提到的,ã字形可以用组合形式表示:单个代码点(ã字符的代码点),或者以分解形式表示:两个代码点(a的代码点后跟代码组合代字号)。

在编组和&之间进行转换在分解的表单中,您可以使用unicodedata模块中的normalize函数。这是一个简短的Python 2演示。

import unicodedata as ud

s = u"Aarão"
print repr(s)

decomp = ud.normalize('NFD', s)
print repr(decomp)

comp = ud.normalize('NFC', decomp)
print repr(comp), comp == s

<强>输出

u'Aar\xe3o'
u'Aara\u0303o'
u'Aar\xe3o' True

答案 1 :(得分:1)

嗯,差异似乎是因为用于编码〜一个字符的两种不同策略。

'Aara\u0303o\n'

包含组合波形符,而

'Aar\xe3o\n'

有〜直接编码。

为什么这是一个问题,你不说。

答案 2 :(得分:1)

unicode字符U + 0303是组合波浪号。它是一个非间距字符,表示它被添加到前一个字符。

您可以在python(Python 2语法)中控制它:

>>> print u'xa\u0303y'
xãy

这意味着在视觉上你无法将其与tilda角色区分开来:U + e3:

>>> print u'x\xe3y'
xãy

但是不同的(unicode)字符串:

>>> u'xa\u0303y' == u'x\xe3y'
False

这意味着当您手动输入单个latin1字符时,Google电子表格包含组合tilda ã