Python re 中的命名反向引用 (?P=name) 问题

Posted

技术标签:

【中文标题】Python re 中的命名反向引用 (?P=name) 问题【英文标题】:Named backreference (?P=name) issue in Python re 【发布时间】:2018-02-11 18:04:23 【问题描述】:

我正在学习 Python 的“re”部分,而命名模式 (?P=name) 让我很困惑,

当我使用re.sub() 对数字和字符进行一些交换时,模式“(?P=name)”不起作用,但模式“\N”和“\g<name>”仍然有意义。代码如下:

[IN]print(re.sub(r'(?P<digit>\d3)-(?P<char>\w4)', r'(?P=char)-(?P=digit)', '123-abcd'))
[OUT] (?P=char)-(?P=digit)
[IN] print(re.sub(r'(?P<digit>\d3)-(?P<char>\w4)', r'\2-\1', '123-abcd'))
[OUT] abcd-123
[IN] print(re.sub(r'(?P<digit>\d3)-(?P<char>\w4)', r'\g<char>-\g<digit>', '123-abcd'))
[OUT] abcd-123

为什么我使用(?P=name)时无法替代? 以及如何正确使用? 我正在使用 Python 3.5

【问题讨论】:

(?P=name) 是模式内反向引用。您不能在替换模式中使用它。 你想用 "?P=name" 达到什么目的??? 【参考方案1】:

(?P=name) 是一个内联(模式内)反向引用。您可以在正则表达式模式中使用它来匹配相应命名捕获组捕获的相同内容,请参阅Python Regular Expression Syntax reference:

(?P=name) 对命名组的反向引用;它匹配之前名为 name 的组匹配的任何文本。

见this demo:(?P&lt;digit&gt;\d3)-(?P&lt;char&gt;\w4)&amp;(?P=char)-(?P=digit)匹配123-abcd&amp;abcd-123,因为“数字”组匹配并捕获123,“字符”组捕获abcd,然后命名的内联反向引用匹配abcd123 .

要替换匹配项,请使用 \1\g&lt;1&gt;\g&lt;char&gt; 语法和 re.sub 替换模式。不要为此目的使用(?P=name)

repl 可以是字符串或函数...反向引用,例如\6,被替换为模式中第6组匹配的子字符串... 在字符串类型的 repl 参数中,除了上述字符转义和反向引用之外,\g&lt;name&gt; 将使用与名为 name 的组匹配的子字符串,如 (?P&lt;name&gt;...) 语法所定义的\g&lt;number&gt;使用对应的组号;因此\g&lt;2&gt; 等价于\2,但在诸如\g&lt;2&gt;0 之类的替换中并没有歧义。 \20 将被解释为对第 20 组的引用,而不是对后跟文字字符“0”的第 2 组的引用。反向引用\g&lt;0&gt; 替换了 RE 匹配的整个子字符串。

【讨论】:

谢谢,现在我知道了,我应该在带有命名组的 re 表达式中使用 并且 会得到匹配的结果(例如 '123')而不是 re 模式(\d3) 再次。感谢您的帮助!【参考方案2】:

您可以查看使用和反向引用的详细信息?P访问:

https://docs.python.org/3/library/re.html

并在浏览器中使用 CTRL+F 来查找 (?P...)。它带有一张漂亮的图表,其中包含有关何时可以使用 ?P=name 的所有说明。

对于这个例子,你在第三次 re.sub() 调用时做的很好。

在所有 re.sub() 调用中,您只能在此方法的第一个字符串参数中使用 ?P=name 语法,而在第二个字符串参数中不需要它,因为您有 \g 语法。

如果您对 ?P=name 是否有用感到困惑,那么它是有用的,但用于通过反向引用已命名的字符串来进行匹配。

示例:您要匹配potatoXXXpotato 并将其替换为YYXXXYY。你可以:

re.sub(r'(?P<myName>potato)(XXX)(?P=myName)', r'YY\2YY', 'potatoXXXpotato')

re.sub(r'(?P<myName>potato)(?P<triple>XXX)(?P=myName)', r'YY\g<triple>YY', 'potatoXXXpotato')

【讨论】:

以上是关于Python re 中的命名反向引用 (?P=name) 问题的主要内容,如果未能解决你的问题,请参考以下文章

python中的正则表达式(re模块)三

Python - Django - 命名 URL 和反向解析 URL

正则——反向引用

在 re.sub 替换模式中处理对捕获组的反向引用

正则表达式——命名分组

python给正则匹配部分命名