Python 看起来相同但编码不同的字符串
我有两个文件:file1.csv和file2.csv,每个文件的第一行也是唯一一行都写着“Aarão”。file1.csv是从谷歌电子表格的“导出为”生成的;文件2.csv是我用nano手动创建的。两个文件均以utf-8编码:Python 看起来相同但编码不同的字符串,python,python-2.7,unicode,utf-8,Python,Python 2.7,Unicode,Utf 8,我有两个文件:file1.csv和file2.csv,每个文件的第一行也是唯一一行都写着“Aarão”。file1.csv是从谷歌电子表格的“导出为”生成的;文件2.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打开它们时,它们看起来是一样的
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中)嗯,这种差异似乎是因为对~a字符使用了两种不同的编码策略
'Aara\u0303o\n'
包含组合平铺字符,而
'Aar\xe3o\n'
具有直接编码的~a
为什么这是一个问题,你不会说。好吧,区别似乎是因为对~a字符使用了两种不同的编码策略
'Aara\u0303o\n'
包含组合平铺字符,而
'Aar\xe3o\n'
具有直接编码的~a
为什么这是一个问题,您不会说。unicode字符U+0303是组合波浪线。它是一个非间隔字符,这意味着它被添加到上一个字符中
'Aara\u0303o\n'
您可以用python控制它(python 2语法):
这意味着,从视觉上看,您无法将其与tilda字符:U+e3:
>>> print u'x\xe3y'
xãy
但是它们是不同的(unicode)字符串:
这仅仅意味着谷歌电子表格中包含了组合tilda,而您手动输入了单个拉丁字符
ãunicode字符U+0303是组合tilde。它是一个非间隔字符,这意味着它被添加到上一个字符中
'Aara\u0303o\n'
您可以用python控制它(python 2语法):
这意味着,从视觉上看,您无法将其与tilda字符:U+e3:
>>> print u'x\xe3y'
xãy
但是它们是不同的(unicode)字符串:
这仅仅意味着谷歌电子表格中包含了组合tilda,而您手动输入单个拉丁字符ã
,正如deceze、Serge和Simon所提到的那样,ã
字形可以以任何一种组合形式表示:单个代码点(用于ã
字符的代码点),或者以分解形式:两个代码点(用于a
的代码点后跟用于组合波浪形的代码点)
要在合成和分解的表单之间进行转换,您可以使用模块中的normalize
功能。下面是一个简短的Python2演示
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
正如deceze、Serge和Simon所提到的,ã
字形可以用组合形式表示:单个代码点(字符的代码点),或者用分解形式表示:两个代码点(字符的代码点后接组合波浪线的代码点)
要在合成和分解的表单之间进行转换,您可以使用模块中的normalize
功能。下面是一个简短的Python2演示
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
好的,对不起。这是一个问题,因为我在file1.csv的相同条件下保存了上千个名称的列表,并且在从相当于file2的文件中读取文本时希望将它们作为停止字。但由于它们是不同的编码,我无法从文件2的文本中正确删除文件1的名称。好的,对不起。这是一个问题,因为我在file1.csv的相同条件下保存了上千个名称的列表,并且在从相当于file2的文件中读取文本时希望将它们作为停止字。但是由于它们是不同的编码,我无法从文件2的文本中正确删除文件1的名称。好的,谢谢。但是我如何将一个转换成另一个呢?因为我想检查它们是否是同一个词。在这种情况下,它的名称相同,但编码不同。@Miguel:不!这不是编码问题。它在视觉上是相同的字形,但有两个不同的字符表示。好的,unicode没有自动将一种表示转换为另一种表示的规定。unicodedata。normalize
可以在合成和分解的形式之间转换。好的,谢谢。但是我如何将一个转换成另一个呢?因为我想检查它们是否是同一个词。在这种情况下,它的名称相同,但编码不同。@Miguel:不!这不是编码问题。它在视觉上是相同的字形,但有两个不同的字符表示。顺便说一句,unicode没有自动将一种表示转换为另一种表示的规定。normalize可以在合成和分解的形式之间进行转换。作为sid建议-由于您运行的是单个脚本,而且更重要的是,在处理非纯ASCII文本时,您最好使用Python3而不是Python2.7。Python3处理文本(默认情况下使用unicode)简化了许多简单任务。(不过,您仍然会面临问题中列出的问题-但是您可以使用内置的open
打开文件,CSV模块也适用于此)以及sid建议-由于您运行的是单个脚本,而且更多的是涉及非纯ASCII文本,因此使用Python3比使用Python2.7要好得多。Python3处理文本(默认情况下使用unicode)简化了许多简单任务。(尽管如此,您仍然会面临问题中列出的问题-但是您可以使用内置的open
打开文件,并且CSV模块也适用于此)