在 Python 中,(?P<group_name>…)
语法允许通过名称引用匹配的字符串:
>>> import re
>>> match = re.search('(?P<name>.*) (?P<phone>.*)', 'John 123456')
>>> match.group('name')
'John'
“P”代表什么?我在官方文档中找不到任何提示。
我很想知道如何帮助我的学生记住这种语法。知道“P”代表(或可能代表)什么会很有用。
既然我们都在猜测,我不妨给出我的:我一直认为它代表 Python。这听起来可能很愚蠢——什么,P 代表 Python?!- 但在我的辩护中,我隐约记得这个线程[强调我的]:
主题:声明 (?P...) 正则表达式语法扩展
来自:Guido van Rossum (gui...@CNRI.Reston.Va.US)
日期:1997 年 12 月 10 日下午 3:36:19
我对 Perl 开发人员(开发 Perl 语言的人员)有一个不同寻常的要求。我希望这个(perl5-porters)是正确的列表。我正在抄送 Python 字符串签名,因为它是我在这里讨论的大部分工作的起源。
你可能知道 Python。我是 Python 的创造者;我计划在今年年底之前发布下一个“主要”版本 Python 1.5。我希望 Python 和 Perl 可以在未来几年共存;异花授粉对两种语言都有好处。(我相信 Larry 在将对象添加到 Perl 5 时对 Python 有很好的了解;O'Reilly 出版了有关这两种语言的书籍。)
您可能知道,Python 1.5 添加了一个新的正则表达式模块,它更接近于 Perl 的语法。我们试图在 Python 的语法中尽可能接近 Perl 语法。但是,正则表达式语法有一些特定于 Python 的扩展,它们都以 (?P 开头。目前有两个:
(?P<foo>...)
与常规分组括号类似,但在
匹配完成后,可以通过符号组名“foo”访问组匹配的文本。
(?P=foo)
匹配与名为“foo”的组匹配的相同字符串。等价于 \1、\2 等,不同之处在于该组是
按名称而不是编号来引用的。我希望这个 Python 特定的扩展不会与 Perl 正则表达式语法的任何未来 Perl 扩展发生冲突。如果您有使用 (?P 的计划,请尽快通知我们,以便我们解决冲突。 否则,如果 (?P 语法可以永久保留用于 Python 特定的语法扩展,那就太好了。 (是有某种扩展注册表吗?)
拉里沃尔回答说:
[...] 目前还没有注册表——你的请求是来自 perl5-porters 外部的第一个请求,所以这是一个带宽相当低的活动。(抱歉,上周甚至更低——我在纽约的 Internet World 休息。)
无论如何,就我而言,在我的祝福下,你肯定有'P'。(显然 Perl 在这一点上不需要 'P'。:-) [...]
所以不知道当初选择P的动机是什么--pattern?占位符?企鹅?——但你可以理解为什么我总是将它与 Python 联系起来。考虑到(1)我不喜欢正则表达式并尽可能避免它们,以及(2)这个线程发生在十五年前,有点奇怪。
图案!该组命名一个(子)模式以供以后在正则表达式中使用。有关如何使用此类组的详细信息,请参阅此处的文档。
Python 扩展。来自 Python 文档:
Perl 开发人员选择的解决方案是使用 (?...) 作为扩展语法。? 括号后立即出现语法错误,因为 ? 没有什么可重复的,所以这并没有引入任何兼容性问题。紧随其后的字符?指示正在使用什么扩展,因此 (?=foo) 是一回事(肯定的前瞻断言),而 (?:foo) 是另一回事(包含子表达式 foo 的非捕获组)。
Python 支持几个 Perl 的扩展,并在 Perl 的扩展语法中添加了扩展语法。如果问号后面的第一个字符是 P,你就知道它是 Python 特有的扩展