How can I combine a positive and negative condition in a regex?
-
19-09-2019 - |
Question
I fairly new to regular expressions and need some help. I need to filter some lines using regex in Perl. I am going to pass the regex to another function so it needs to be done in a single line.
I want to select only lines that contain "too long"
and that don't begin with "SKIPPING"
Here are my test strings:
SKIPPING this bond since maturity too long
TKIPPING this bond since maturity too long
SLAPPING this bond since maturity too long
Hello this maturity too long
this is too long
hello there
The regex rule should match the following on 'too long":
SKIPPING this bond since maturity too long
SLAPPING this bond since maturity too long
Hello this maturity too long
this is too long
and it should skip:
"hello there" because it doesn't contain 'too long'
"SKIPPING this bond since maturity too long" because it containst 'SKIPPING'
Solution
/^(?!SKIPPING).*too long/
OTHER TIPS
Personally, I'd do this as two separate regex just to make it clearer.
while (<FILE>)
{
next if /^SKIPPING/;
next if !/too long/;
... do stuff
}
I suspect you maybe after a single regex however I prefer to split into something more readable like this:
use strict;
use warnings;
for my $line ( <DATA> ) {
next if $line =~ m/^SKIPPING/;
next if $line !~ m/too long/;
# do something with $line
chomp $line;
say "Found: ", $line, ':length=', length( $line );
}
__DATA__
SKIPPING this bond since maturity too long
TKIPPING this bond since maturity too long
SLAPPING this bond since maturity too long
Hello this maturity too long
this is too long
hello there
Use a lookahead; see this explanation of regex lookaround.
^(?!SKIPPING).*too long
/^(?<!SKIPPING).*too long$/
Matches the lines you're looking for. The dollar sign at the end causes it to match only strings that end with "too long".
Hope this helps!
Using negative lookbehind:
(?<!^SKIPPING)too long$