这个问题与可变长度后视无关,因为它可能有一个没有负面后视的解决方案。
在 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)。
关于python - 匹配表示正则表达式集的模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48025095/