有人可以解释这个正则表达式的贪婪

时间:2012-06-20 15:17:16

标签: regex regex-greedy

我有一些文字,其中每行文字都有一些好词和一些坏(不需要的)词。所以模式可能看起来像这样

good1-good2 good3 bad1-good4-bad2 some more good words
good1-good2 good3 bad1 bad2 
good1-good2 good3 bad1 bad2 bad3

现在我需要拒绝接下来的所有内容,包括第一个坏词 所以

good1-good2 good3 bad1-good4-bad2 some more good words应该成为good1-good2 good3

good1-good2 good3 bad1 bad2应该成为good1-good2 good3

good1-good2 good3 bad1 bad2 bad3应该成为good1-good2 good3

我正在使用python所以这就是我所做的

p=re.compile('([\w \d-]+) (bad1|bad2|bad3).+',re.I)
m=p.search('good1-good2 good3 bad1-good4-bad2 ')
m.group(1)

这会给good1-good2 good3 这是我想要的但是

m=p.search('good1-good2 good3 bad1 bad2 ')
m.group(1)

返回good1-good2 good3 bad1 我认为这是因为+是贪婪的,所以+中的([\w \d-]+)继续匹配字符直到行尾,然后它回溯找到最后一个坏词,在这种情况下是bad2但是当我这样做时

p=re.compile('([\w \d-]+) (bad1|bad2|bad3).+',re.I)
m=p.search('good1-good2 good3 bad1 bad2 bad3')
m.group(1)

它再次返回good1-good2 good3 bad1。 你能解释一下吗?因为我对正则表达式greediness的理解可能存在问题?虽然我已经想出来解决这个问题 通过使用像([\w \d-]+?) (bad1|bad2|bad3).+这样的正则表达式,但我仍然不明白为什么使用([\w \d-]+) (bad1|bad2|bad3).+总是返回第一个坏词(在这种情况下为bad1)?

感谢您的时间。

修改 但是假设我的模式只有好词而没有坏词 good1-good2 good3--only good words那么正则表达式应该是什么? 我尝试了这个正则表达式([\w \d-]+?) ?(bad1|bad2|bad3)?.*,但这会返回模式的第一个字母。

1 个答案:

答案 0 :(得分:3)

关于这种情况:

m=p.search('good1-good2 good3 bad1 bad2 ')

你是对的。 ([\w \d-]+)是贪婪的,所以它尽可能“吃”并回溯。

关于这种情况:

m=p.search('good1-good2 good3 bad1 bad2 bad3')

您可能没有看到的是,您的.+必须与至少一个字符匹配。这就是正则表达式无法将bad3作为坏词的原因:如果确实如此,那么.+的字符就会用完以匹配任何内容。因此,它再次回溯到bad2。将您的.+更改为.*以查看差异。这只是因为你碰巧在第一种情况下有一个额外的空间, bad2 ,事情“按预期”完成了。

换句话说,一些不幸的巧合让你感到困惑;但你对贪婪的理解是合理的。

修改

对于问题的编辑部分,由@lovesh撰写,来自以下评论:

([\w \d-]+?) ?(bad1|bad2|bad3|$)