How do I write a regex to match any string that doesn't meet a particular pattern? I'm faced with a situation where I have to match an (A and ~B) pattern.
You could use a look-ahead assertion:
(?!999)\d{3}
This example matches three digits other than 999
.
But if you happen not to have a regular expression implementation with this feature (see Comparison of Regular Expression Flavors), you probably have to build a regular expression with the basic features on your own.
A compatible regular expression with basic syntax only would be:
[0-8]\d\d|\d[0-8]\d|\d\d[0-8]
This does also match any three digits sequence that is not 999
.
If you want to match a word A in a string and not to match a word B. For example: If you have a text:
1. I have a two pets - dog and a cat
2. I have a pet - dog
If you want to search for lines of text that HAVE a dog for a pet and DOESN'T have cat you can use this regular expression:
^(?=.*?\bdog\b)((?!cat).)*$
It will find only second line:
2. I have a pet - dog
findstr
command. It affords only a tiny subset of the capabilities you expect to find in a regex tool; lookahead is not among them. (I just added the findstr tag myself.) –
Nomography Match against the pattern and use the host language to invert the boolean result of the match. This will be much more legible and maintainable.
notnot, resurrecting this ancient question because it had a simple solution that wasn't mentioned. (Found your question while doing some research for a regex bounty quest.)
I'm faced with a situation where I have to match an (A and ~B) pattern.
The basic regex for this is frighteningly simple: B|(A)
You just ignore the overall matches and examine the Group 1 captures, which will contain A.
An example (with all the disclaimers about parsing html in regex): A is digits, B is digits within <a tag
The regex: <a.*?<\/a>|(\d+)
Demo (look at Group 1 in the lower right pane)
Reference
\d
with [[:digit:]]
. The first reference mentions it is specific to Perl and PHP: "There is a variation using syntax specific to Perl and PHP that accomplishes the same." –
Outer The complement of a regular language is also a regular language, but to construct it you have to build the DFA for the regular language, and make any valid state change into an error. See this for an example. What the page doesn't say is that it converted /(ac|bd)/
into /(a[^c]?|b[^d]?|[^ab])/
. The conversion from a DFA back to a regular expression is not trivial. It is easier if you can use the regular expression unchanged and change the semantics in code, like suggested before.
replace
str.replace(/re/g, '')
, then there's no need to rejoin them. also if you throw in a nice trailing \s? like str.replace(/\re\s?/g, '')
then you get rid of any duplicate spaces you would have from something being replaced in the middle of a string –
Lallygag (B)|(A)
then use what group 2 captures...
My answer here might solve your problem as well:
https://mcmap.net/q/25873/-regex-replace-everything-except-a-particular-pattern
- Instead of Replace, you would use Match.
- Instead of group
$1
, you would read group$2
. - Group
$2
was made non-capturing there, which you would avoid.
Example:
Regex.Match("50% of 50% is 25%", "(\d+\%)|(.+?)");
The first capturing group specifies the pattern that you wish to avoid. The last capturing group captures everything else. Simply read out that group, $2
.
© 2022 - 2024 — McMap. All rights reserved.
findstr
tag since all answers here are not valid for the tag. – Quatrain