这个Python正则表达式应该匹配模式的重复,然后是可选模式,我做错了什么?

时间:2018-02-07 22:54:22

标签: python regex

以下是我的尝试:

import re

r = re.compile(r'(?P<label>(?:[^_]+)+)(_r(?P<repeat_num>\d+))?')

def main():
    s1 = 'abc_123'
    s2 = 'abc_123_r1'

    m1 = r.match(s1)
    m2 = r.match(s2)

    print(m1.groups())
    print(m2.groups())

if __name__ == "__main__":
    main()

我希望第一个字符串s1abc_123组匹配label,而repeat_num没有任何内容。

我希望第二个字符串s2abc_123组匹配labelrepeat_num匹配“1”。

在两种情况下,实际结果都会停在abc

2 个答案:

答案 0 :(得分:0)

看起来它部分归因于[^_]位,它匹配“除了下划线之外的任何字符”。

我无法立即找到能够正确捕获这些令牌的解决方案;我强烈建议您使用RegExr来播放正则表达式,以便弄清楚如何正确匹配这些部分。

答案 1 :(得分:0)

您的模式与输入字符串的_abc之间的123不匹配。您需要修改第一个捕获组才能处理这些组。

直接翻译可能会遇到困难,因为将_r1块与正常的额外块(如_123)区分开来有点困难。我认为下面的模式是正确的,但你应该仔细检查它总能做到你所期望的:

(?P<label>[^_]+(?:_[^_]+)*?)(?:_r(?P<repeat_num>\d+))?

如果您始终要求在文本的第一部分中至少有两个带下划线的分隔组(例如abc_123,但从不只是abc123本身),则应更换*?+?