我使用的是包含letter ü的以下文字摘要:
test für fur test
以下是代码:
import re
for m in re.finditer(r, line, re.IGNORECASE | re.UNICODE):
print 'match: ', m.group(0)
print 'offset: ', m.start()
有三个正则表达式:
r = ur'\bf(\u0075)r\b' # finds 'fur', as expected
r = ur'\bf(\xc3\xbc)r\b' # finds 'für', as expected
r = ur'\bf(\u00FC)r\b' # does not find 'für'
表达式#1和#3相似;唯一的区别是Unicode点(u
vs ü
)。 #3为什么不起作用?
我可以使用#2,但它的可读性较差。
答案 0 :(得分:2)
以下是我的测试结果。
>>> print re.findall(ur'\bf(\u0075)r\b', "test für fur test", re.I|re.U)
['u']
>>> print re.findall(ur'\bf(\xc3\xbc)r\b', "test für fur test", re.I|re.U)
['\xc3\xbc']
>>> print re.findall(ur'\bf(\u00FC)r\b', "test für fur test", re.I|re.U)
[]
这些完全符合您的结果。我注意到第二个案例的匹配是['\xc3\xbc']
,然后它击中了我。 "test für fur test"
是非unicode字符串。
这是我用unicode字符串进行的第二组测试。
>>> print re.findall(ur'\bf(\u0075)r\b', u"test für fur test", re.I|re.U)
[u'u']
>>> print re.findall(ur'\bf(\xc3\xbc)r\b', u"test für fur test", re.I|re.U)
[]
>>> print re.findall(ur'\bf(\u00FC)r\b', u"test für fur test", re.I|re.U)
[u'\xfc']
正则表达式匹配字符串中的二进制表示。所以unicode字符串匹配unicode字符,非unicode字符串匹配UTF-8编码字符。
如果您无法选择使用的刺痛类型,则可以始终使用unicode()
。
>>> print re.findall(ur'\bf(\u00FC)r\b', unicode("test für fur test", "utf-8"), re.I|re.U)
[u'\xfc']
在你的情况下
for m in regex.finditer(r, unicode(line, "utf-8"), regex.IGNORECASE | regex.UNICODE):
print 'match: ', m.group(0)
print 'offset: ', m.start()
注意强>
根据.py文件的文件编码,ur'\bf(ü)r\b'
也应该有效。
>>> print re.findall(ur'\bf(ü)r\b', u"test für fur test", re.I|re.U)
[u'\xfc']
答案 1 :(得分:2)
我觉得你在这里让自己感到困惑。您正在使用的字符串显然不是Unicode字符串。
如果是,您将按预期获得\u00fc
。
>>> import re
>>> m = re.search(ur'f(\xc3\xbc|\u0075|\u00fc)r', u'für')
>>> m.group(1)
u'\xfc'
您仍然需要满足Unicode等效性。完全分解的等效U+00FC是常规u
,后跟COMBINING DIAERESIS (U+0308)。可能你会想要运行unicodedata.normalize('NFC', thing)
并确保你的正则表达式总是寻找组合的等价物(或相反地去'NFD'
并完全分解);或者转换到据称可以更好地处理这个问题的regex
module。
如果您正在处理UTF-8并且您知道自己是,那么通常建议您在将其读入Python后将其解码为Unicode字符串。参见例如http://nedbatchelder.com/text/unipain.html