当两个连续的组或第一个组之间缺少空格时,模式将失败

2024-03-28 18:09:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望下面的模式为所有finditer使用提供相同的结果。我需要找到未转移的\g,这就是我使用(?:[^\\])的原因。你知道吗

import re

p = re.compile(r"(?:[^\\])\\g<([a-zA-Z_][a-zA-Z\d_]*)>")

for m in p.finditer(r"</\g<name_1>\g<name_2>\\g<escaped>>"):
    print(m.group(1))

print('---')

for m in p.finditer(r"</\g<name_1> \g<name_2>\\g<escaped>>>"):
    print(m.group(1))

print('---')

for m in p.finditer(r"\g<name_1>\g<name_2>\\g<escaped>>"):
    print(m.group(1))

这里是相应的输出,其中第一个输出中缺少name_2,最后一个输出中缺少name_1。你知道吗

name_1
---
name_1
name_2
---
name_2

为什么一个空格的使用使得两个组总是可以找到的?如何使用阻断组或文本^的起始选项?如何改变我的模式以避免这种失败?你知道吗


Tags: namein文本importrefor模式group
1条回答
网友
1楼 · 发布于 2024-03-28 18:09:50

您的模式非常接近,但它要求序列以一些非反斜杠字符开始:

[^\\]

此字符串:

</\g<name_1>\g<name_2>>

有一个以非反斜杠(/)开始的序列,该序列根据需要继续读取\g<,但随后是一个不以非反斜杠开始的序列,后跟\g<(它立即跳入\g)。添加空格可以使其工作,因为空格提供了必要的非反斜杠字符。你知道吗

您可以扩充模式,使初始非反斜杠字符成为可选的:

p = re.compile(r"(?:[^\\])?\\g<([a-zA-Z_][a-zA-Z\d_]*)>")

但是,因为这里的括号是非分组(?:...)变体,所以删除整个括号表达式更简单:

p = re.compile(r"\\g<([a-zA-Z_][a-zA-Z\d_]*)>")

得到的正则表达式与示例输入一起工作。你知道吗


编辑:要解决\g<前面不能有反斜杠的要求,请使用“负向后看”:

p = re.compile(r"(?<!\\)\\g<([a-zA-Z_][a-zA-Z\d_]*)>")

被“检查以确保它不在那里”的字符串必须是固定长度的,并且单个字符\是固定长度的。如果搜索是在字符串的开头运行的,则负look behind允许匹配;如果是在中间,则“look behind”以确保不存在带圆括号的固定长度子表达式。你知道吗

相关问题 更多 >