使用正则表达式反向引用作为Python

时间:2016-12-10 22:07:25

标签: python regex

我试图将正则表达式的一部分用作正则表达式的后续部分的输入。

到目前为止我所做的(未通过断言):

import re
regex = re.compile(r"(?P<length>\d+)(\d){(?P=length)}")
assert bool(regex.match("3123")) is True
assert bool(regex.match("100123456789")) is True

打破这一点,第一个数字表示之后应该匹配多少个数字。在第一个断言中,我得到3作为第一个字符,这意味着之后应该有正好三个数字,否则有超过9个数字。如果超过9位数,则需要展开第一组并检查其余数字。

正则表达式3(\d){3}将与第一个断言正确匹配,但是我无法使正则表达式与大括号{}被赋予正则表达式反向引用的一般情况相匹配:{(?P=length)}

使用re.DEBUG标志调用正则表达式:

subpattern 1
  max_repeat 1 4294967295
    in
      category category_digit
subpattern 2
  in
    category category_digit
literal 123
groupref 1
literal 125

看起来大括号{123)和}125)在其内部有反向引用时被解释为文字。
如果没有反向引用,例如{3},我可以看到{3}被解释为max_repeat 3 3

是否可以使用反向引用作为正则表达式的一部分?

1 个答案:

答案 0 :(得分:3)

无法将反向引用作为模式中的限制量词参数。为了解决您当前的任务,我可以建议以下代码(请参阅解释逻辑的内联注释):

import re
def checkNum(s):
    first = ''
    if s == '0':
        return True # Edge case, 0 is valid input
    m = re.match(r'\d{2,}$', s) # The string must be all digits, at least 2
    if m:
        lim = ''
        for i, n in enumerate(s):
            lim = lim + n
            if re.match(r'{0}\d{{{0}}}$'.format(lim), s):
                return True
            elif int(s[0:i+1]) > len(s[i+1:]):
                return False

print(checkNum('3123'))         # Meets the pattern (123 is 3 digit chunk after 3)
print(checkNum('1234567'))      # Does not meet the pattern, just 7 digits
print(checkNum('100123456789')) # Meets the condition, 10 is followed with 10 digits
print(checkNum('9123456789'))   # Meets the condition, 9 is followed with 9 digits

请参阅Python demo online

re.match一起使用的模式(在字符串开头处锚定模式)是{0}\d{{{0}}}$,如果3\d{3}$传递给3123,它将看起来像checkNum 3方法。它将匹配以$开头的字符串,然后将匹配3个数字后跟字符串结束标记(div)。