Reputation: 4642
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.
Upvotes: 178
Views: 278602
Reputation: 655239
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
.
Upvotes: 200
Reputation: 8680
My answer here might solve your problem as well:
https://stackoverflow.com/a/27967674/543814
$1
, you would read group $2
.$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
.
Upvotes: 0
Reputation: 41838
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
How to match pattern except in situations s1, s2, s3
How to match a pattern unless...
Upvotes: 9
Reputation: 5330
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
Upvotes: 32
Reputation: 41397
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.
Upvotes: 4
Reputation: 537
pattern - re
str.split(/re/g)
will return everything except the pattern.
Test here
Upvotes: 2
Reputation: 69342
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.
Upvotes: 15