如何在Python中使用正则表达式排除特定字符串?

10 投票
2 回答
39510 浏览
提问于 2025-04-18 10:23

我想要匹配像这样的字符串:

45 meters?
45, meters?
45?
45 ?

但不想匹配像这样的字符串:

45 meters you?
45 you  ?
45, and you?

在这两种情况下,问号必须在字符串的最后。所以,基本上我想排除所有包含“you”这个词的字符串。

我试过以下的正则表达式:

'\d+.*(?!you)\?$'

但它却匹配了第二种情况(可能是因为 .* 的原因)。

2 个回答

15

有一个很不错的技巧可以用来在正则表达式中排除一些匹配项,你可以在这里使用:

>>> import re
>>> corpus = """
... 45 meters?
... 45?
... 45 ?
... 45 meters you?
... 45 you  ?
... 45, and you?
... """
>>> pattern = re.compile(r"\d+[^?]*you|(\d+[^?]*\?)")
>>> re.findall(pattern, corpus)
['45 meters?', '45?', '45 ?', '', '', '']

不过,这个方法的一个缺点是,当排除条件生效时,会出现空匹配,但这些空匹配很容易过滤掉:

>>> filter(None, re.findall(pattern, corpus))
['45 meters?', '45?', '45 ?']

它是怎么工作的:

这个技巧的关键在于我们只关注捕获的组……所以在选择的左边部分 - \d+[^?]*you(也就是“数字后面跟着非问号的字符,再后面是‘you’”)匹配的是你想要的内容,然后我们就把它忘掉。只有当左边的部分不匹配时,右边的部分 - (\d+[^?]*\?)(也就是“数字后面跟着非问号的字符,再后面是问号”)才会被匹配,并且这个部分会被捕获。

13

你可以试试这个正则表达式,它可以匹配所有不以字符串 you? 结尾的行。

^(?!.*you).*\?$

解释:

这个正则表达式使用了一个叫做“负向前瞻”的技巧。简单来说,它的意思是检查哪些行包含字符串 you。它会匹配所有不包含字符串 you 的行。

演示

撰写回答