【问题标题】:Python regex \w doesn't match combining diacritics?Python regex \w 不匹配组合变音符号?
【发布时间】:2010-07-06 20:54:27
【问题描述】:

我有一个包含变音符号的 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 markdown 处理器在上面的组合变音符号上遇到了问题,但最后一行有一个 ́)

有没有办法将变音符号与\w结合起来?我不想规范化文本,因为这个文本来自文件名,我还不想做一个完整的“文件名 unicode 规范化”。这是 Python 2.5。

【问题讨论】:

    标签: python regex unicode diacritics unicode-normalization


    【解决方案1】:

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

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

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

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

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

    【讨论】:

      【解决方案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>
      

      我知道你说你不想规范化,但我认为这个解决方案不会有问题,因为你只是规范化要匹配的字符串,而不必更改文件名自己什么的。

      【讨论】:

      • 是的,这会告诉我是否有匹配,但是在匹配之后,我会提取匹配的组,然后对它们进行处理。如果我使用你的方法,那么我之后的字节将与文件名中的字节不同
      • 我明白了。您是否知道字符串在使用组合变音符号时是否一致(总是组合,或者至少总是在单个字符串中组合或不组合)?如果是这样,您可以根据需要再次将结果标准化为 NFC 或 NFD。否则,我认为您将不得不诉诸技巧来检测原始字符串中组合变音符号的位置,并尝试使用该信息仅分解所需的字符(这当然比仅仅分解或不分解所有内容更有效)全部)。
      • 或者也许只是更改表达式并使用您感兴趣的组合变音符号的范围,并使用类似 \w[\u0300-\u036F] 的东西?而不仅仅是 \w
      • 不,输入与使用组合变音符号的方式不一致。有些使用组合字符,有些使用组合变音符号
      猜你喜欢
      • 2013-06-27
      • 2017-07-02
      • 2018-01-31
      • 1970-01-01
      • 1970-01-01
      • 2011-04-02
      • 2019-07-13
      • 2023-01-31
      • 2020-12-09
      相关资源
      最近更新 更多