Skip to main content
 首页 » 编程设计

python之匹配表示正则表达式集的模式

2025年01月19日39JustinYoung

这个问题与可变长度后视无关,因为它可能有一个没有负面后视的解决方案。

在 Python3 中,我尝试匹配的模式可能已达到使用正则表达式所能达到的极限,但我仍想尝试一下。我实际上是在尝试避免使用解析工具。

我要匹配的是表示正则表达式集的模式。因此将匹配以下内容。

[abc] 
[1-9\n\t] 
[ \t\]] 
[\\\]] 
[[\\\\\\\]] 

方括号不能嵌套,比如[[]],我们要匹配[[]。

不过,由于 \] 表示转义括号,我们需要跳过它们。但是必须接受诸如 \\] 之类的模式。以下将不匹配。

[\] 
[\\\] 
[abc\\\] 

规则最终匹配从 [ 到第一个 ],它前面没有奇数个 \。

负向回顾似乎不起作用,因为它必须有固定的长度。

编辑:Wiktor Stribiżew 给出了一个有趣的解决方案

re.compile(r'\[[^]\\]*(?:\\.[^]\\]*)*\]') 

编辑:Rawing 的上述简化版本

r'\[(?:\\.|[^]\\])*\]' 

请您参考如下方法:

你可以使用

re.compile(r'\[[^]\\]*(?:\\.[^]\\]*)*]', re.DOTALL) 

参见 regex demo .

详情

  • \[ - 一个 [字符
  • [^]\\]* - 除 ] 以外的 0 个或更多字符和 \
  • (?: - 匹配以下序列的非捕获组的开始:
    • \\. - 一个 \ char 后跟任何 char
    • [^]\\]* - 除 ] 以外的 0 个或更多字符和 \
  • )* - 非捕获组内模式的零次或多次重复
  • ] - 一个 ]字符。

正则表达式遵循 unroll-the-loop principle .根据输入的不同,它可能会工作很多,甚至比非展开版本快 10 倍以上, r'\[(?:\\.|[^]\\])*]' ,这是基于无限量化的交替组,导致大量冗余回溯步骤。

请注意,当初始 [ 出现时,上面的正则表达式可能会失败前面有一个反斜杠。在这些情况下,您将需要

r'(?<!\\)(?:\\{2})*(\[[^]\\]*(?:\\.[^]\\]*)*])' 

查看这个正则表达式演示

这里的主要区别是 (?<!\\)(?:\\{2})* , 一个 (?<!\\)如果当前位置前面带有 \,则匹配失败的否定后视字符,和 (?:\\{2})*匹配两个文字反斜杠的 0+ 次重复。模式的其余部分包含在捕获括号中,当找到匹配项时,您只需访问 match.group(1)以获得正确的值(value)。