使用正则表达式反向引用作为Python中正则表达式的一部分

Bry*_*nta 6 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
Run Code Online (Sandbox Code Playgroud)

打破这一点,第一个数字表示之后应该匹配多少个数字.在第一个断言中,我得到一个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
Run Code Online (Sandbox Code Playgroud)

看起来braces {(123)和}(125)在它们内部有反向引用时被解释为文字.
当没有反向引用时,例如{3},我可以看到它{3}被解释为max_repeat 3 3

使用反向引用作为正则表达式的一部分可能吗?

Wik*_*żew 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
Run Code Online (Sandbox Code Playgroud)

在线查看Python 演示。

使用的模式re.match(将模式锚定在字符串的开头){0}\d{{{0}}}$看起来就像3\d{3}$3123传递给checkNum方法一样。它将匹配以 开头的字符串3,然后精确匹配后跟字符串结尾标记 ( $) 的 3 位数字。