Regex problem, match if line contains <a>, unless it also contains <b>

J

James Dyer

I'm having problems getting a regex to work.
Basically, given two search parameters ($search1 and $search2), it
should allow me to filter a log file such that lines with the $search1
string in are printed, unless the $search2 string is also in that line
somewhere (either before or after $search1).

I'm creating my regex like this:
$compiled_regex = qr/^(?!.*$search2)$search1(?!.*$search2)/;

I then use it:

while( <> ) {
next if( $_ !~ /$compiled_regex/ );
print $_ . "\n";
}

With the following test data:

2004-02-18 04:06:50 1AtIua-0001Hh-00 -> (e-mail address removed) R=lookuphost T=remot
e_smtp H=mxhost-1.foo.bar [0.0.0.0]
2004-02-19 04:02:02 1AtfNx-0008DC-00 -> (e-mail address removed) R=lookuphost T=remot
e_smtp H=mxhost-1.foo.bar [0.0.0.0]
2004-02-19 04:07:26 1AtfO5-0008Gs-00 -> (e-mail address removed) R=lookuphost T=remot
e_smtp H=mxhost-1.foo.bar [0.0.0.0]

If $search1 is set to 'sysadmin', and search2 is set to '0008Gs',
none of the lines in the data are displayed, whereas I would expect the
first two to be displayed.

With this test data:
foo
foo foo
foo foo foo
foo bar
bar foo
foo bar foo
foo bar bar
bar foo bar
bar foo foo
bar
bar bar
bar bar bar

$search1 set to 'foo', and $search2 set to 'bar', I get the
expected results (foo, foo foo and foo foo foo displayed).

I just can't figure out why nothing is being displayed in my first test case.
My gut instinct is that it's got something to do with the special'ish
characters in the data ('-', '>' etc.), but I'm not sure.

Any thoughts?

J
 
J

James Dyer

OK, I was being stupid, and really not thinking about what my regex
was actually doing.
I've now solved the problem - for those of you who are interested,
this appears to work:

$compiled_regex = qr/^(?!.*$search2).*$search1/;

J
 
T

toylet

I've now solved the problem - for those of you who are interested,
this appears to work:
$compiled_regex = qr/^(?!.*$search2).*$search1/;

what's the meaning of "?!" in the regex?
 
T

toylet

I've now solved the problem - for those of you who are interested,
what's the meaning of "?!" in the regex?

I figured it out. need to force the context of the $! variable.

print int($!) . $!;

int($i) prints the error number, 2nd $! prints the message.
 
N

nobull

$compiled_regex = qr/^(?!.*$search2)$search1(?!.*$search2)/;

Ignoring the possiblity that $search1 maches a newline, the second
(?!.*$search2) is redundant. It can never fail to match since the re
engine wouldn't get as that far if there was a match for $search2
anywhere in the data.

$compiled_regex = qr/^(?!.*$search2)$search1/s;
2004-02-18 04:06:50 1AtIua-0001Hh-00 -> (e-mail address removed) R=lookuphost T=remot
If $search1 is set to 'sysadmin', and search2 is set to '0008Gs',

You are only looking for $search1 at the start of the string. You
probably wanted.

$compiled_regex = qr/^(?!.*$search2).*$search1/s;

Note - using a single regex for this is probably not a good idea
unless you are forced into doing so by the fact that you are calling
an existing function that you can't modify and that takes a single
regex as an argument.

If you are not compelled to use a single regex it is clearer, and
probably faster to use two.

/$search1/ && !/$search2/
Any thoughts?

Well since you ask...

This topic has been frequently discussed in the Perl newsgroups that
exist on Usenet. I think you should have done a search before you
posted. Having decided you wanted to post I think you should have
done so to a newsgroup that still exists. This one doesn't (see FAQ)
so very few people will see what you post here.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top