10

我有一个包含变音符号的 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。

4

2 回答 2

7

我刚刚注意到 pypi 上有一个新的“ regex ”包。(如果我理解正确,它是一个新包的测试版本,有朝一日将取代 stdlibre包)。

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

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

它(目前)是一个非标准库包,我不知道它的准备情况如何(而且它不是二进制发行版),但你可能想试一试,因为它似乎是您问题的最简单/最“正确”的答案。(否则,我认为您可以明确使用字符范围,如我对上一个答案的评论中所述)。

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

于 2010-07-06T12:54:27.257 回答
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>

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

于 2010-06-29T15:41:38.923 回答