【问题标题】:Python regex - matching character sequences using prior matched charactersPython regex - 使用先前匹配的字符匹配字符序列
【发布时间】:2017-04-24 11:51:17
【问题描述】:

我希望匹配诸如“zxxz”和“vbbv”之类的字符串,其中一个字符后跟一对与第一个不匹配的相同字符,然后是第一个。因此,我确实希望匹配诸如“zzzz”和“vvvv”之类的字符串。

我从以下匹配所有这些示例的 Python 正则表达式开始:

(.)(.)\2\1

为了排除第二组(“zzzz”,“vvvv”),我尝试了这个修改:

(.)([^\1])\2\1

我的理由是第二组可以包含任何单个字符,只要它与第一组中匹配的字符不同。

不幸的是,这似乎不起作用,因为它仍然匹配“zzzz”和“vvvv”。

根据 Python 2.7.12 文档:

\数字

匹配同号组的内容。组从 1 开始编号。例如,(.+) \1 匹配“the the”或“55 55”,但不匹配“thethe”(注意组后面的空格)。此特殊序列只能用于匹配前 99 个组中的一个。如果 number 的第一个数字是 0,或者 number 是 3 个八进制数字,则不会被解释为组匹配,而是被解释为具有八进制值 number 的字符。 在字符类的 '[' 和 ']' 内,所有数字转义都被视为字符。

(我强调了)。

我觉得这句话模棱两可,或者至少不清楚,因为它向我暗示数字转义应该解析为集合中的单个排除字符,但这似乎没有发生。

此外,以下正则表达式似乎也无法正常工作:

(.)[^\1][^\1][\1]

这似乎与“zzzz”或“zxxz”不匹配。

【问题讨论】:

    标签: python regex string


    【解决方案1】:

    您想在第二个捕获组中对\1 执行negative lookahead assertion (?!...),然后它将起作用:

    r'(.)((?!\1).)\2\1'
    

    测试你的例子:

    >>> import re
    >>> re.match(r'(.)((?!\1).)\2\1', 'zxxz')
    <_sre.SRE_Match object at 0x109b661c8>
    >>> re.match(r'(.)((?!\1).)\2\1', 'vbbv')
    <_sre.SRE_Match object at 0x109b663e8>
    >>> re.match(r'(.)((?!\1).)\2\1', 'zzzz') is None
    True
    >>> re.match(r'(.)((?!\1).)\2\1', 'vvvv') is None
    True
    

    【讨论】:

    • 谢谢。你能解释一下导致你选择否定前瞻断言的想法吗?我不确定我将来如何知道我需要使用一个。
    • 另外,你知道为什么字符集方法不起作用吗?不能在字符集中使用组引用吗?那是我不理解的文档部分。
    • 字符集是文字。所以[^\1] 是在搜索任何不是 \ 或 1 字符的字符。
    • 啊,这就是“所有数字转义都被视为字符”的意思。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 2011-09-01
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    相关资源
    最近更新 更多