Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to match a line which has a set pattern but only match it if a particular word doesn't appear in the rest of the line.

If this word  my3.exe appears in the line I wish to skip it.

This is the original code

if (/my background error (\d+): (.+)/ ) { do something with the matched line }
This is how I changed it
if (/my background error (\d+): (.+(?!my3\.exe))/ ) { do something with the matched line }
It is still however picking up the records that have "my background error" and "my3.exe" in them. Can somebody pinpoint what I am doing wrong ?

Replies are listed 'Best First'.
Re: negated word issue
by davido (Cardinal) on Mar 01, 2012 at 13:51 UTC

    Go easy on yourself:

    if( ! /my3\.exe/ and /my background error (\d+): (.+)/ ) { # do something with $1 and $2 }

    Sometimes breaking it into two separate problems is the clearer solution.


    Dave

      Agreed this is the simplest approach. thanks
Re: negated word issue
by kcott (Archbishop) on Mar 01, 2012 at 14:20 UTC

    Changing your regex to

    /my background error (\d+):(?!.+my3\.exe)/

    seems to capture what you're after.

    Here's a few tests:

    $ perl -Mstrict -Mwarnings -E 'while (<>) { if (/my background error ( +\d+):(?!.+my3\.exe)/ ) { say $1 } }' blah blah my background error 1234: blah blah 1234 blah blah my background error 1234: blah blah my3.exe blah blah blah my background error 1234: blah blah my4.exe blah 1234 blah blah my background error 1234: my3.exe blah blah my background error 1234:my3.exe 1234 ^C

    Note the last one with 1234:my3.exe is a match: which seems to follow the pattern you're describing. If you don't want that line either, use .* instead of .+, i.e. change (?!.+my3\.exe) to (?!.*my3\.exe).

    UPDATE

    I noticed you wanted to capture the text after the error number as well as that number. The solution above doesn't do that. The following regex will:

    /my background error (\d+): ((?!.*my3\.exe).+)/

    Retested:

    $ perl -Mstrict -Mwarnings -E 'while (<>) { if (/my background error ( +\d+): ((?!.*my3\.exe).+)/ ) { say qq{$1 = \"$2\"} } else { say q{NO M +ATCH} } }' blah blah my background error 1234: blah blah 1234 = "blah blah" blah blah my background error 1234: blah blah my3.exe blah NO MATCH blah blah my background error 1234: blah blah my4.exe blah 1234 = "blah blah my4.exe blah" blah blah my background error 1234: my3.exe NO MATCH blah blah my background error 1234:my3.exe NO MATCH blah blah my background error 1234: my4.exe 1234 = "my4.exe" ^C

    -- Ken

      Thanks. I was still trying to figure this out when you posted the update.