检测单词存在的python正则表达式

2024-06-26 14:47:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使用python正则表达式检测句子中是否有单词。同时,我希望能够否定它

import re
re.match(r'(?=.*\bfoo\b)', 'bar red foo here')

这段代码可以工作,但我不明白为什么我需要把.*放在那里。 也要否定它,我不知道该怎么做。 我试过:

re.match(r'(?!=.*\bfoo\b)', 'bar red foo here')

但它不起作用。 我的最终目标是这样组合它们:

re.match(r'(?=.*\bfoo\b)(?!=.*\bbar\b)', 'bar red foo here')

Tags: 代码importreherefoomatchbarred
3条回答

更新
刚刚发现Pythonre.match()有一个隐含的^锚。
换句话说,它将只在字符串的开头匹配,
奇怪的是,与Java不同,它不需要匹配整个字符串

但要注意的是,将连续的正向和负向相结合向前看
如Stribnez回答中所述,如果未锚定到
,可能会产生意外结果 某物文本或BOS锚定^

对于一般用法,不要依赖于(或如果)在某些语言中的事实
match()函数意味着BOS锚定^(可能还有EOS$)。
始终将其中一个(或两个)放在那里。这样就可以使用它了
搜索()中也可以使用。并且可以移植到其他语言

若要查看“串联前瞻”中的“消极”和“积极”是如何导致问题的,
以这个棘手的独立表达式(?=.*\bfoo\b)(?!.*\bbar\b)

可以这样检查:

因为它是系列,所以两个断言必须同时匹配
在字符串中的位置

如果两者在字符串中的位置相同,则否定断言
当它找到一个下游与它的内容不匹配的地方时,可以满足

假设不存在锚定,这是一个开口上游
(在示例中的搜索位置和bar文本之间)for
不希望存在的内容,仍然满足肯定/否定的内容
断言对

示例:
(?=.*\bfoo\b)(?!.*\bbar\b)
匹配
bar red foo

**  Grp 0 -  ( pos 1 , len 0 )  EMPTY 

b<here>ar red foo

这表明在位置1,两个断言都得到满足

结论:
1.始终使用锚定,即使它们是隐含的。
2.避免使用任何语言的match()函数,请改用search()

结束更新


无论您使用积极或消极的前瞻性,
如果不使用正确的语法,它将无法工作

看看这个(?!=.*\bfoo\b)

这意味着下一个字符不能是后跟
的等号= 最多到下一个foo的贪婪字符数。这是不允许的

因此,它将不匹配= ab foo,但它将匹配“=(这里)ab foo”

下一个问题是,如果您不给断言任何锚定的内容
它将使用凹凸移动位置到字符之间的位置
那将使它满意

您正在寻找的负面前瞻修正如下
^(?!.*\bfoo\b)


供参考:

(?=..)  Positive lookahead
(?<=..) Positive lookbehind
(?!..)  Negative lookahead
(?<!..) Negative lookbehind   

而且,它们可以在任何地方混合和嵌套

要检测字符串中是否存在单词,您需要一个正向前瞻

(?=.*\bfoo\b)

需要.*来启用比仅在字符串开始处搜索更远的搜索(re.match将搜索锚定在字符串开始处)

要检查字符串中是否没有单词,请使用负前瞻

(?!.*\bbar\b)
 ^^^

因此,将它们结合起来:

re.match(r'(?=.*\bfoo\b)(?!.*\bbar\b)', input)

将在包含整词foo且不包含整词bar的字符串中找到匹配项

您需要.*,因为re.match()尝试将模式与字符串的开头匹配。如果要搜索整个字符串,请使用re.search()

正如你可以做if re.search(...):,你也可以做if not re.search(...):

相关问题 更多 >