使用repr()时,两个看似相同的unicode字符串会有所不同,但我该如何解决这个问题呢?

时间:2014-10-01 22:20:29

标签: python python-2.7 unicode

我有两个unicode字符串列表,一个包含从文本文件中拾取的单词,另一个包含目录中声音文件名列表,从其扩展名中删除。一个列表中的一些单词与另一个单词中的单词相同。我尝试使用re.search(ur'(?iu)\b%s\b' % string1, string2),fnmatch甚至简单的string1 == string2类型比较找到匹配项,所有这些都在我自己输入第一个列表进行测试时有效,但在使用从中检索的实际单词列表时失败了一个文本文件。

在进行测试以找出原因时,我监控了两个列表中的越南词chào。使用isinstance(string, unicode)确认它们都是unicode。但是,在两个字符串上使用repr()在一个案例中返回u'ch\xe0o',在另一个案例中返回u'cha\u0300o'。所以很明显为什么他们不匹配。

所以我似乎找到了原因,但我不知道如何解决这个问题。我尝试使用.decode('utf-8'),因为我认为\xe0可能是utf-8。但它所做的就是返回Unicode编码错误。此外,如果两个字符串都是unicode并且代表相同的单词,那么它们不应该是相同的吗?做print('%s Vs. %s' % (string1, string2))返回chào Vs. chào我在这里迷失了。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

正如您所发现的,某些Unicode字符可以指定为不同的方式,可以是单个代码点,也可以是常规代码点加上组合代码点。角色\u0300COMBINING GRAVE ACCENT,会在前一个角色上添加重音符号。

将字符串固定到公共表示的过程称为规范化。您可以使用the unicodedata module执行此操作:

def n(str):
    return unicodedata.normalize('NFKC', str)

>>> n(u'ch\xe0o') == n(u'cha\u0300o')
True

答案 1 :(得分:4)

问题似乎是unicode中严重重音的模糊表示。以下是LATIN SMALL LETTER A WITH GRAVE,此处为COMBINING GRAVE ACCENT,与“' a'变得或多或少与第一个完全相同。所以两个相同角色的表示。事实上,unicode有一个术语:unicode equivalence

要在python中实现此功能,请在比较前对字符串使用unicodedata.normalize。我试过NFC'返回你的模式' ch \ xe0o'两个字符串。