问题
I need check if a string contains the pattern: starts with "A" followed by zero or more spaces and then anything but not "B".
So, the following must match: "A"
. "AX"
, "A X"
, "A "
, "A XB"
The following strings must not match: "AB"
, "A B"
My naive attempt was A\s*(?!B)
, but it matches the undesirable "A B"
.
回答1:
If you just need to get true or false, you may put the \s*
into the lookahead:
Regex.IsMatch(s, @"A(?!\s*B)")
It finds A
that has no 0+ whitespaces followed with B
after it.
See the regex demo.
In your pattern, A\s*(?!B)
, the negative lookahead can be executed after any 0+ whitespaces, and once a whitespace not followed with B
is found, a valid match is returned (that happens due to backtracking that is possible thanks to \s*
quantified pattern).
If you need to actually match the A
and the whitespace after it, but if these whitespaces are not followed with B
, use the pattern from my comment.
(?>A\s*)(?!B)
This pattern matches:
(?>A\s*)
- an atomic group, matchesA
, then 0+ whitespaces with no backtracking into the group pattern allowed(?!B)
- noB
after the spaces, or the whole match is failed.
回答2:
Update:
Based on the comment below, use this pattern A\s*B|(A)
and check against group #1
Use this pattern A\s*+(?!B)\w*
Demo
# A\s*+(?!B)\w*
A # "A"
\s # <whitespace character>
*+ # (zero or more)(possessive)
(?! # Negative Look-Ahead
B # "B"
) # End of Negative Look-Ahead
\w # <ASCII letter, digit or underscore>
* # (zero or more)(greedy)
or based on your attempt, use this A\s*+(?!B)
回答3:
The attempt doesn't work because it matches the "A"
before the " B"
, I would suggest attempting to take the negative approach, and writing A\s*B
and use all non-matching lines. For example with grep grep -v "A\\s*B"
.
If the A is needed and there are non-A
lines you can search twice, grep A | grep -v "A\\s*B"
.
来源:https://stackoverflow.com/questions/45463437/regular-expression-with-optional-part-and-negative-lookahead