问题
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)- noBafter 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