更新
刚发现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,两个断言都得到了满足。
结论:
1.始终使用锚点,即使它们是暗示的。
2.避免使用任何语言的match()函数,改用search()。
无论您使用正向先行断言还是负向先行断言,如果不使用正确的语法,它都无法正常工作。
看看这个(?!=.*\bfoo\b)。这意味着下一个字符不能是等号=,后面跟着一堆字符直到下一个foo。这是不允许的。因此,它将不匹配= ab foo,但它将匹配'=(here) ab foo'。
下一个问题是,如果您没有给断言提供任何锚定内容,它会使用一个bump-along来将位置移动到一个在其中字符之间满足它的位置。所需的负向先行断言更正如下:^(?!.*\bfoo\b)。
供参考:
(?=..) Positive lookahead
(?<=..) Positive lookbehind
(?!..) Negative lookahead
(?<!..) Negative lookbehind
此外,它们可以混合和嵌套在任何地方。
'foo' in sentence and 'bar' not in sentence
的语法呢?(或者你想要实现的其他操作) - Two-Bit Alchemistre.match(r'\bfoo\b', s) and not re.match(r'\bbar\b', s)
- L3viathans
中的'substring'
,你能解释一下吗? - Two-Bit Alchemist\b
——一个单词边界。尝试使用in
和not in
来模拟它。 - Wiktor Stribiżew