2

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

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 我认为因为+是贪婪的所以+in([\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)?.*,但这会返回模式的第一个字母。

4

1 回答 1

3

关于本案:

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

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

然而,关于这种情况:

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

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

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

编辑

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

([\w \d-]+?) ?(bad1|bad2|bad3|$)
于 2012-06-20T15:30:57.767 回答