How about using negative lookahead? This way, you check to see whether what follows 'request(' actually contains the BADSTRING, and fails if that is the case.
use strict; $/ = ""; # Set up for slurp mode my $data = <DATA>; # Grab the entire file to a string. my %matches = $data =~ /^request\( # start of record (?!BADSTRING) # Fails if BADSTRING is present ([^\n]+) # Captures $blah1 \n # Match the newline [^,]+, # Match anything up to the comma ([^\n]+) # Capture $blah2. Everything from /mgx; # the comma to the next \n foreach ( keys %matches ) { print "$_ : $matches{$_}\n"; } __DATA__ request(goodstring START_TIME,some goodness request(BADSTRING START_TIME,some bad stuff request(randomstring START_TIME,more goodness request(whatever you are
This gives:
goodstring : some goodness randomstring : more goodness
Thanks to pzbagel for his excellent sample data :)
This uses several neat tricks. /g repeats the match until the string is empty. /m allows embedded newlines in the string to match. Calling the regex in list context and assigning it to a hash gives us a nice little summary to dump afterwards.
Disadvantages to this approach is of course the amount of memory used by $data and %matches. Malformed data may break /g, and of course the relative illegibility of the regex may be a problem. If your datasamples aren't too big, it might work, though.
Hope this helps, and I welcome (and appreciate) any criticism on my regex-programming style.
pernod
--
Mischief. Mayhem. Soap.
In reply to Re: grab only if pattern matches previous line
by pernod
in thread grab only if pattern matches previous line
by nkpgmartin
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |