我想检测一个单词是否在使用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')
答案 0 :(得分:4)
要检测字符串中是否存在单词,您需要正向前瞻:
python
(?=.*\bfoo\b)
是必要的,以便能够在字符串开始时进行更远的搜索(.*
锚定搜索字符串的开头)。
要检查字符串中是否包含任何字词,请使用否定前瞻:
re.match
所以,结合它们:
(?!.*\bbar\b)
^^^
会在包含整个单词re.match(r'(?=.*\bfoo\b)(?!.*\bbar\b)', input)
且不包含整个单词foo
的字符串中找到匹配项。
答案 1 :(得分:1)
您需要.*
因为re.match()
尝试将模式匹配到字符串的开头。如果要搜索整个字符串,请使用re.search()
。
就像您可以if re.search(...):
一样,您也可以if not re.search(...):
答案 2 :(得分:1)
的更新强>
刚发现Python re.match()有一个隐含的^
锚点
换句话说,它只会在字符串的开头匹配,
奇怪的是,与Java不同,它不需要它匹配整个字符串。
警告虽然结合顺序正面和负面前瞻,但是
如在Stribnez的回答中,如果没有锚定到中,可能会产生意想不到的结果
一些东西。文字文本或BOS锚^
。
对于一般用法,不要依赖某种语言(或如果)的事实
match()函数表示BOS锚点^
(可能还有EOS $
)。
将一个(或两个)放在那里。这种方式可以使用
在 search()中也是如此。并可移植到其他语言。
要了解阴性和积极的,串联前瞻可能会导致问题,
采取这个棘手的独立表达式(?=.*\bfoo\b)(?!.*\bbar\b)
可以这样检查:
由于它是串联,因此两个断言必须在相同的情况下匹配 在字符串中的位置。
给两个字符串中的相同位置,否定断言
当找到下游与其内容不匹配的地方时,可以满足。
假设不存在任何锚定,这将打开上游
(在搜索位置和示例中的bar
文字之间)为
存在的不良内容,仍将满足正/负
断言对。
例:
(?=.*\bfoo\b)(?!.*\bbar\b)
匹配
bar red foo
** Grp 0 - ( pos 1 , len 0 ) EMPTY
b<here>ar red foo
这表明在位置1处,两个断言都得到满足。
结论(S):
1.始终使用锚,即使它们是隐含的
2.避免使用任何语言的match()函数,而是使用search()。
结束更新
如果你使用积极或消极的前瞻,那无关紧要 如果你没有使用正确的语法,它就不会起作用。
看看这个(?!=.*\bfoo\b)
这表示下一个字符不能是等号=
,后跟
直到下一个foo
的贪婪数字。这是不允许的。
因此,它与= ab foo
不匹配,但它会匹配&#39; =(此处)ab foo&#39;。
接下来的问题是,如果你没有给断言任何东西来锚定 它会使用一个凸起来将位置移动到字符之间的位置 这将满足它。
您正在寻找的负向前瞻的修正是这个
^(?!.*\bfoo\b)
供参考:
(?=..) Positive lookahead
(?<=..) Positive lookbehind
(?!..) Negative lookahead
(?<!..) Negative lookbehind
并且,它们可以混合并嵌套在任何地方。