I'm having trouble getting the desired output using negative lookahead.
import re
text = "$FOO FOO $BAR BAR"
# Expected. Return words without 'F'.
re.findall(r"\b(?!F)\w+", text)
> ['BAR', 'BAR']
# Expected. Return words without 'B'.
re.findall(r"\b(?!B)\w+", text)
> ['FOO', 'FOO']
# Unexpected. Return words without '$'.
re.findall(r"\b(?!\$)\w+", text)
> ['FOO', 'FOO', 'BAR', 'BAR']
The first two work as expected. I expect the last one to return the list ['FOO', 'BAR']
matching words without the "$" character. Because it's a special character, I've tried various ways to escape it but haven't found the right solution.
You actually need to fix the pattern in the following way:
\b(?<!\$)\w+
See the Python demo .
The reason is that \b(?!\$)\w+
is equal to \b\w+
since $
cannot be matched with \w
, so no need to restrict the first char matched with \w
with the (?!\$)
negative lookahead. You need to restrict the char that comes immediately before the first char matched wit \w
, and that is done with a negative lookbehind , here, (?<!\$)
.
import re
text = "$FOO FOO $BAR BAR"
print(re.findall(r"\b(?<!\$)\w+", text))
# > ['FOO', 'BAR']
Now, as you say (?<=^)(??\$)\w+|(?<=\s)(?!\$)\w+
works for you, you can now see that you may safely remove the lookaheads from the regex as they do not do anything meaningful, and the regex becomes (?<=^)\w+|(?<=\s)\w+
. This expression can be shrunk further into a slim (?<!\S)\w+
pattern that matches any one or more word chars that are immediately preceded with start of string or a whitespace.
Thanks to Charles for putting me on the right track. I had an incorrect understanding of how boundary characters function.
import re
text = "FOO $FOO FOO $BAR BAR"
re.findall('(?<=^)(?!\$)\w+|(?<=\s)(?!\$)\w+', text)
> ['FOO', 'FOO', 'BAR']
Replacing \b
with a negative look-behind that matched a space or the beginning of a string gives the desired output.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.