python match只捕获第一组和最后一组 - 我误解了什么吗?

Jak*_*hem 4 python regex match

我正在研究一个应该与一系列作者匹配的Python脚本,我正在使用re-module.我遇到了意想不到的事情,我已经能够将它简化为以下非常简单的例子:

>>> import re
>>> s = "$word1$, $word2$, $word3$, $word4$"
>>> word = r'\$(word\d)\$'
>>> m = re.match(word+'(?:, ' + word + r')*', s)
>>> m.groups()
('word1', 'word4')
Run Code Online (Sandbox Code Playgroud)

所以我正在定义一个'基本'正则表达式,它匹配我输入的主要部分,带有一些可识别的功能(在这种情况下我使用了$-signs),而不是我尝试匹配一个单词加上可能的附加单词列表.

我原本预计m.groups()会显示:

>>> m.groups()
('word1', 'word2', 'word3', 'word4')
Run Code Online (Sandbox Code Playgroud)

但显然我做错了什么.我想知道为什么这个解决方案不起作用以及如何改变它,以便我得到我正在寻找的结果.顺便说一句,这是Linux机器上的Python 2.6.6,如果重要的话.

Joe*_*ett 7

虽然你是匹配每个$word#$,但第二个捕获组不断被匹配的最后一个项目取代.

我们来看看调试器:

>>> expr = r"\$(word\d)\$(?:, \$(word\d)\$)*"
>>> c = re.compile(expr, re.DEBUG)
literal 36
subpattern 1
  literal 119
  literal 111
  literal 114
  literal 100
  in
    category category_digit
literal 36
max_repeat 0 65535
  subpattern None
    literal 44
    literal 32
    literal 36
    subpattern 2
      literal 119
      literal 111
      literal 114
      literal 100
      in
        category category_digit
    literal 36
Run Code Online (Sandbox Code Playgroud)

如您所见,只有2个捕获组:subpattern 1subpattern 2.每次$word#$发现另一个时,subpattern 2都会被覆盖.

至于潜在的解决方案,我建议使用re.findall()而不是re.match():

>>> s = "$word1$, $word2$, $word3$, $word4$"
>>> authors = re.findall(r"\$(\w+)\$", s)
>>> authors
['word1', 'word2', 'word3', 'word4']
Run Code Online (Sandbox Code Playgroud)

  • @JakobvanBethlehem你还应该查看[`re.VERBOSE`](http://docs.python.org/library/re.html#re.VERBOSE),它可以让你拆分你的正则表达式,添加评论等等编译它.基本上,在每行写入RE的部分,用惯常的`#`添加注释(并确保将它放在三引号中).当它们特别复杂时,可以使您的RE更具可读性. (2认同)