我正在开发一个Python脚本,它应该与一系列作者匹配,而我正在使用re
- 模块。我遇到了意想不到的事情,我已经能够将它简化为以下非常简单的例子:
>>> import re
>>> s = "$word1$, $word2$, $word3$, $word4$"
>>> word = r'\$(word\d)\$'
>>> m = re.match(word+'(?:, ' + word + r')*', s)
>>> m.groups()
('word1', 'word4')
所以我正在定义一个'基本'正则表达式,它匹配我输入的主要部分,带有一些可识别的功能(在这种情况下我使用$
- 符号),而不是我尝试匹配一个单词加上可能的其他单词列表。
我原本预计m.groups()
会显示:
>>> m.groups()
('word1', 'word2', 'word3', 'word4')
但显然我做错了什么。我想知道为什么这个解决方案不起作用以及如何改变它,以便我得到我正在寻找的结果。顺便说一句,这是Linux机器上的Python 2.6.6,如果重要的话。
答案 0 :(得分: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
如您所见,只有2个捕获组:subpattern 1
和subpattern 2
。每次找到$word#$
时,subpattern 2
都会被覆盖。
对于潜在的解决方案,我建议使用re.findall()
代替re.match()
:
>>> s = "$word1$, $word2$, $word3$, $word4$"
>>> authors = re.findall(r"\$(\w+)\$", s)
>>> authors
['word1', 'word2', 'word3', 'word4']
答案 1 :(得分:4)
正则表达式中只有两个捕获组。请改为re.findall(word, s)
。
regex
module支持重复捕获。
答案 2 :(得分:1)
如果您有可选或重复的捕获组,请执行以下操作:
(?:, \$(word\d)\$)*
正则表达式只有一个地方可以返回在该组中捕获的文本,尽管它匹配了字符串的3个部分,因此它包含 last 这样的子字符串。
要查找所有子字符串,您可以使用findall
或将字符串标记为其他分隔符。
答案 3 :(得分:0)
你可以避免像这样的正则表达式:
>>> s = "$word1$, $word2$, $word3$, $word4$"
>>> s.replace('$','').split()
['word1,', 'word2,', 'word3,', 'word4']
使用正则表达式,您可以改为使用findall()
:
>>> re.findall(word, s)
['word1', 'word2', 'word3', 'word4']