Python正则表达式\ w与组合变音符号不匹配?

时间:2010-06-29 13:25:12

标签: python regex unicode diacritics unicode-normalization

我有一个UTF8字符串,结合了变音符号。我想将它与\w正则表达式序列匹配。它匹配具有重音符号的字符,但如果存在组合变音符号的拉丁字符则不匹配。

>>> re.match("a\w\w\wz", u"aoooz", re.UNICODE)
<_sre.SRE_Match object at 0xb7788f38>
>>> print u"ao\u00F3oz"
aoóoz
>>> re.match("a\w\w\wz", u"ao\u00F3oz", re.UNICODE)
<_sre.SRE_Match object at 0xb7788f38>
>>> re.match("a\w\w\wz", u"aoo\u0301oz", re.UNICODE)
>>> print u"aoo\u0301oz"
aóooz

(看起来SO降价处理器在上面的组合变音符有问题,但最后一行有一个)

无论如何将变音符号与\w相结合?我不想规范化文本,因为这个文本来自文件名,我不想要做一个完整的'文件名unicode规范化'。这是Python 2.5。

2 个答案:

答案 0 :(得分:6)

我刚刚注意到pypi上有一个新的“regex”包。 (如果我理解正确的话,它是有一天会替换stdlib re包的新包的测试版本)。

在unicode方面似乎有更多可能性。例如,它支持\X,用于匹配单个字素(无论是否使用组合)。它还支持在unicode属性,块和脚本上进行匹配,因此您可以使用\p{M}来引用组合标记。前面提到的\X相当于\P{M}\p{M}*(不是组合标记的字符,后跟零个或多个组合标记)。

请注意,这会使\X或多或少等同于.的unicode,而不是\w,因此在您的情况下,\w\p{M}*就是您所需要的。

它是(现在)一个非stdlib包,我不知道它是多么准备好(它不是二进制发行版),但你可能想尝试一下,因为它似乎是你问题最容易/最“正确”的答案。 (否则,我认为你明确使用字符范围,如我对前一个答案的评论中所述)。

另请参阅this page,其中包含有关unicode正则表达式的信息,这些信息可能还包含一些有用的信息(并且可以作为regex包中实现的一些内容的文档)。

答案 1 :(得分:2)

您可以使用unicodedata.normalize将组合变音符号组合成一个unicode字符。

>>> import re
>>> from unicodedata import normalize
>>> re.match(u"a\w\w\wz", normalize("NFC", u"aoo\u0301oz"), re.UNICODE)
<_sre.SRE_Match object at 0x00BDCC60>

我知道你说你不想规范化,但我不认为这个解决方案会有问题,因为你只是将字符串规范化以匹配,而不必更改文件名本身或其他什么。