Python正则负前瞻:如何让re.search仅校验首个'monday'实例
The problem with your current regex is that even though .*? is non-greedy, when the first monday fails the negative lookahead ((?!night)), the regex engine backtracks and allows .*? to match past that first monday until it finds another one that satisfies the lookahead. That's why it's incorrectly matching the second monday in your sample text.
To fix this, we need to ensure the regex stops at the first occurrence of monday and doesn't backtrack past it. We can do this using a tempered greedy token instead of .*?, which will match any characters except those that start the word monday:
import re rex = r'today(?:(?!monday).)*monday (?!night)' txt = 'today [blah blah] monday night but [blah blah] monday morning' m = re.search(rex, txt) print(m) # Output: None (exactly what you want!)
How This Works:
(?:(?!monday).)*: This non-capturing group matches any character (.) only if it doesn't start the sequencemonday((?!monday)). This guarantees we stop at the firstmondayand never skip over it.- After reaching the first
monday, the negative lookahead(?!night)checks if the following text is notnight. If it isnight, the entire match fails—and since we can't backtrack to find anothermonday,re.search()returnsNone.
Test Case Where First 'Monday' Is Valid:
If your text had a valid first monday (followed by something other than night):
txt = 'today [blah blah] monday morning but [blah blah] monday night' m = re.search(rex, txt) print(m.group()) # Output: 'today [blah blah] monday '
This correctly matches up to the first monday because it passes the lookahead check.
内容的提问来源于stack exchange,提问作者Tokyo D

