tobbo
tobbo

Reputation: 437

Regex matching multiple negative lookaheads

I'm trying to match a string (using a Perl regex) only if it doesn't start with "abc:" or "defg:", but I can't seem to find out how. I've tried something like

^(?:(?!abc:)|(?!defg:))

Upvotes: 30

Views: 21915

Answers (7)

Stephan Stamm
Stephan Stamm

Reputation: 1153

Lookahead (?=foo), (?!foo) and lookbehind (?<=foo), (?<!foo) do not consume any characters.

You can do multiple assertions:

^(?!abc:)(?!defg:)

or:

^(?!defg:)(?!abc:)

...and the order does not make a difference.


You can use De Morgan (as other answers do):

(NOT A) AND (NOT B) <=> NOT (A OR B) 

...and shorten the expression to:

^(?!abc:|defg:)

Upvotes: 40

AJP
AJP

Reputation: 43

Use this regex:

^(?!abc:|defg:)\s*\w+

This will avoid line start with "abc:" and "defg:" as you want.

Upvotes: 2

blackSmith
blackSmith

Reputation: 3154

This will do the task:

^(?!(defg|abc):).*

Upvotes: 0

vks
vks

Reputation: 67968

^(?:(?!abc:|defg:).)*$

Try this. See the demo at http://regex101.com/r/hQ9xT1/18.

Upvotes: 0

Abecee
Abecee

Reputation: 2393

… or we could have dropped the alternation from the original expression:

^(?:(?!abc:)(?!defg:))

Upvotes: 1

Gilles Qu&#233;not
Gilles Qu&#233;not

Reputation: 185219

Try doing this:

^(?!(?:abc|defg):)

Upvotes: 9

ssr1012
ssr1012

Reputation: 2589

Could you please try this:

use strict;
use warnings;
use Cwd;

while(<DATA>)
{
    my $line=$_;
    print $line unless($line=~m/^(abc|defg*)/m);
}

__DATA__
ebc this is testing ebc
dbc this is testing dbc
defg this is testing defg
abc this is testing abc
defg this is testing defg

Upvotes: 0

Related Questions