3

我正在学习rePython 的“”部分,命名模式(?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'\2-\1', '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

4

2 回答 2

4

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

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

请参阅此演示(?P<digit>\d{3})-(?P<char>\w{4})&(?P=char)-(?P=digit)匹配123-abcd&abcd-123因为“数字”组匹配并捕获123,“字符”组捕获abcd然后命名的内联反向引用匹配abcd123

要替换匹配项,请使用\1替换模式\g<1>\g<char>语法。re.sub请勿(?P=name)用于此目的:

repl可以是字符串或函数...反向引用,例如\6,被替换为模式中第 6 组匹配的子字符串...

在字符串类型的 repl 参数中,除了上述字符转义和反向引用之外,\g<name>还会使用由名为 name 的组匹配的子字符串,如(?P<name>...)语法. \g<number>使用对应的组号;\g<2>因此等价于\2,但在诸如\g<2>0. \20将被解释为对第 20 组的引用,而不是对第 2 组的引用,后跟文字字符“0”。反向引用\g<0>替换了 RE 匹配的整个子字符串。

于 2017-09-03T07:47:45.287 回答
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')
于 2017-09-03T07:50:56.690 回答