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

Named backreference (?P=name) issue in Python re

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

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

[IN]print(re.sub(r'(?P<digit>\d{3})-(?P<char>\w{4})', r'(?P=char)-(?P=digit)', '123-abcd'))
[OUT] (?P=char)-(?P=digit)
[IN] print(re.sub(r'(?P<digit>\d{3})-(?P<char>\w{4})', r'-', '123-abcd'))
[OUT] abcd-123
[IN] print(re.sub(r'(?P<digit>\d{3})-(?P<char>\w{4})', r'\g<char>-\g<digit>', '123-abcd'))
[OUT] abcd-123

为什么我用(?P=name)替换失败?
以及如何正确使用它?
我正在使用 Python 3.5

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

(?P=name)
A backreference to a named group; it matches whatever text was matched by the earlier group named name.

参见this demo(?P<digit>\d{3})-(?P<char>\w{4})&(?P=char)-(?P=digit)匹配123-abcd&abcd-123因为"digit"组匹配并捕获123,"char"组捕获abcd 然后命名的内联反向引用匹配 abcd123.

要替换匹配项,请使用 </code>、<code>\g<1>\g<char> 语法和 re.sub 替换模式。不要为此目的使用 (?P=name)

repl can be a string or a function... Backreferences, such as </code>, are replaced with the substring matched by group 6 in the pattern... <br/><br/>In string-type repl arguments, in addition to the character escapes and backreferences described above, <strong><code>\g<name> will use the substring matched by the group named name, as defined by the (?P<name>...) syntax. \g<number> uses the corresponding group number; \g<2> is therefore equivalent to </code>, but isn’t ambiguous in a replacement such as <code>\g<2>0. </code> would be interpreted as a reference to group 20, not a reference to group 2 followed by the literal character '0'. The backreference <code>\g<0> substitutes in the entire substring matched by the RE.

您可以查看使用和反向引用的详细信息 ?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'YYYY', 'potatoXXXpotato')

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