命名正则表达式组"(?P<group_name>regexp)"中的"P"代表什么?

324

在Python中,(?P<group_name>…)语法允许通过给它一个名称来引用匹配到的字符串:

>>> import re
>>> match = re.search('(?P<name>.*) (?P<phone>.*)', 'John 123456')
>>> match.group('name')
'John'

"P"代表什么?我在官方文档中找不到任何提示。

我希望能够得到一些关于如何帮助我的学生记住这个语法的想法。知道"P"代表什么(或可能代表什么)会很有用。


50
P代表占位符 - kev
4
既然只是猜测,我推测Ken Thompson可能是嬉皮士的同情者,“P”代表“广藿香”。 - aaronasterling
3
这个问题已经被添加到Stack Overflow正则表达式FAQ中的“分组”部分。 - aliteralmind
3
提醒一下:regex 模块支持使用 (?<name>...) 语法和当前的 (?P<name>...) 语法来命名分组。 - AXO
14
顺便提一下,如果使用match.groups(有一个s),您将会悄悄地得到一个包含所有组的元组 -_- groups('name') => ('John', '123456'),而您实际上想要的是 group('name') => 'John'希望这能为某人节省时间。 - szmoore
显示剩余3条评论
3个回答

407
既然我们都在猜测,那我也来猜一下:我一直认为它代表Python。这可能听起来很愚蠢——P代表Python?!但作为我的辩护,我依稀记得这个线程:(链接) 引用:
主题:Claiming (?P...) regex syntax extensions
发件人:Guido van Rossum (gui...@CNRI.Reston.Va.US)
日期:1997年12月10日下午3:36:19
我有一个针对Perl开发人员(开发Perl语言的人)的特殊请求。我希望这个(perl5-porters)是正确的清单。我将抄送Python string-sig,因为大部分我正在讨论的工作都源自此。
您可能已经知道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扩展冲突。如果您计划使用(?P,请尽快告诉我们,以便我们可以解决冲突。否则,最好将(?P语法永久保留用于Python特定的语法扩展。(是否有某种扩展注册表?)

Larry Wall回答道:

[...]到目前为止还没有注册表——你们是perl5-porters外部的第一批请求,所以它是一个非常低带宽的活动。(很抱歉上周甚至更低—I在纽约参加了互联网世界大会。)

无论如何,就我而言,你肯定可以拥有'P',我给予祝福。(显然,此时Perl不需要'P'。:-) [...]

所以我不知道最初选择P的动机是什么——模式?占位符?企鹅?但您可以理解为什么我一直将其与Python相关联。考虑到(1)我不喜欢正则表达式并尽可能避免使用它们,以及(2)这个线程发生在十五年前,这有点奇怪。


9
“Python-specific extension” 可能是指针对 Python 特定的扩展。 - jamesmortensen
89
哇,你找到了一些好的和相关的历史数据! Guido 文章的解释是,“P” 代表“Python 特定扩展”。我理解他的意思是这样的。请确认翻译是否准确。 - Eric O. Lebigot
1
是的,这对我来说看起来很明确。因此,有趣的是 Perl 和 PCRE 最初只是因为 Python 是第一个支持命名捕获组的语言而抄袭了它的语法。但它们也支持 (?<group_name>…) 语法,似乎是最受欢迎的——即使 Java 现在也支持它。 - Alan Moore
6
这是一个非常棒的尴尬回答,并且成功地进行了辩护:)。起初,我认为这太蠢了。但最终,我完全同意了。 +1 - Anubis
6
我喜欢即使是Python的创造者涉及到Perl时也使用奇怪和神秘的句法,而Perl社区完全接受了这一点。如果你试图将Perl特定的扩展/句法添加到Python中,那么会出现鲜血淋漓的场面。 - Keith Ripley
显示剩余3条评论

38

Python扩展。来自Python文档:

Perl开发人员选择的解决方案是使用(?...)作为扩展语法。 括号后面紧跟着?是一个语法错误,因为?没有要重复的内容, 所以这不会引入任何兼容性问题。紧随?之后的字符指示使用了什么扩展, 所以(?=foo)是一种东西(正向先行断言)而(?:foo)是另一种东西 (包含子表达式foo的非捕获组)。

Python支持Perl的几个扩展并添加了一个扩展语法到Perl的扩展语法中。 如果问号后的第一个字符是P,你就知道它是一个特定于Python的扩展

https://docs.python.org/3/howto/regex.html


1
很好!这证实了DSM的感觉。 - Eric O. Lebigot

21

Pattern!(模式!)这个组在正则表达式中用来命名(子)模式以供后续使用。有关此类组如何使用的详细信息,请参见此处的文档


4
这是一个很好的记忆方法:(?P<name>…) 表示“模式名称”。“正则表达式”中的所有内容都是模式,因此仅标记(?P<...>...)组作为模式有点奇怪。但对于我的学生来说,这已经足够了。 :) - Eric O. Lebigot
5
不要教授错误的知识给学生。当你追求精确性时,这些知识比你想象的更难以摆脱。例如,一些概念对我来说需要多达5年的时间才能消化。矛盾的是,鼓励随意交谈,但必须清晰明确 - 例如,向学生完整地讲解您之前的评论(也许修正最后一句话)。 - n611x007

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接