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

6

我正在尝试将正则表达式的一部分作为后续正则表达式的输入。

目前我所拥有的(未能通过断言):

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
在正则表达式中使用反向引用是否可行?

5
很不幸,你不能在量词中放置反向引用。这就是生活。 - Casimir et Hippolyte
2
你只能在实际匹配文本中使用反向引用,而不能在重复量词或字符类等内容中使用。 - BrenBarn
1个回答

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演示
在使用re.match时(将模式锚定在字符串开头),所使用的模式为{0}\d{{{0}}}$,如果将3123传递给checkNum方法,则该模式将看起来像3\d{3}$。它将匹配以3开头的字符串,然后将匹配正好3个数字,并跟随着字符串结束标记$

验证9位以上的数字组怎么办?1501234567890应该是false。 - Bryce Guinta
我能理解我的措辞可能会让人感到困惑。我试图突出字符串的上下文敏感性质。 - Bryce Guinta
好的,关键是你需要先获取正则表达式构建所需的数据,然后动态地构建模式。 - Wiktor Stribiżew
根据您的回答,我可以看出如何处理n位数字。将数字字符串的长度分为两部分,基于 len(str(len(s)-1))len(s) - len(str(len(s)-1))。最终我通过计算数字字符来进行了一种回溯。 - Bryce Guinta
1
好的,我明白你的意思。前n个数字可能是限定量词参数。 - Wiktor Stribiżew
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接