我有一些文字,其中每行文字都有一些好词和一些坏(不需要的)词。所以模式可能看起来像这样
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)?.*
,但这会返回模式的第一个字母。
答案 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|$)