Karl_H
Karl_H

Reputation: 83

Find strings that do not begin with something

This has been gone over but I've not found anything that works consistently... or assist me in learning where I've gone awry.

I have file names that start with 3 or more digits and ^\d{3}(.*) works just fine. I also have strings that start with the word 'account' and ^ACCOUNT(.*) works just fine for these.

The problem I have is all the other strings that DO NOT meet the two previous criteria. I have been using ^[^\d{3}][^ACCOUNT](.*) but occasionally it fails to catch one. Any insights would be greatly appreciated.

Upvotes: 0

Views: 109

Answers (2)

dognose
dognose

Reputation: 20899

Demorgan's law says: !(A v B) = !A ^ !B.

But unfortunately Regex itself does not support the negation of expressions. (You always could rewrite it, but sometimes, this is a huge task).

Instead, you should look at your Programming Language, where you can negate values without problems:

let the "matching" function be "match" and you are using match("^(?:\d{3}|ACCOUNT)(.)") to determine, whether the string matches one of both conditions. Then you could simple negate the boolean return value of that matching function and you'll receive every string that does NOT match.

Upvotes: 0

John Kugelman
John Kugelman

Reputation: 361605

^[^\d{3}][^ACCOUNT](.*)

That's definitely not what you want. Square brackets create character classes: they match one character from the list of characters in brackets. If you put a ^ then the match is inverted and it matches one character that's not listed. The meaning of ^ inside brackets is completely different from its meaning outside.

In short, [] is not at all what you want. What you can do, if your regex implementation supports it, is use a negative lookahead assertion.

^(?!\d{3}|ACCOUNT)(.*)

This negative lookahead assertion doesn't match anything itself. It merely checks that the next part of the string (.*) does not match either \d{3} or ACCOUNT.

Upvotes: 1

Related Questions