http://qs321.pair.com?node_id=1212995

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

Hi Monks

I'm continuing my exploration of Perl and currently exploring regular expressions.

For this simple test, I have a small string of KEY=value pairs, separated by ';' characters. I am trying to identify if a particular KEY has a certain value and a different KEY does not contain a value.

I have code which follows which does this with two regexs:

#!/usr/bin/env perl use strict; use warnings; use 5.016; for (<DATA>) { chomp; print "Match: $_\n" if /name=bob/ and not /flags=.*?cat.*?;/; } __DATA__ name=bob;flags=human;age=10 name=tiddles;flags=cat,black;age=3 name=bob;flags=cat,white;age=6

In this simple example, I'm looking to get the line which matches a name of 'bob' and flags does not contain 'cat'. This code works and returns the single matching line.

However, I tried combining the regexes and using lookaheads to match multiple conditions, but this is currently failing. My code for this follows

#!/usr/bin/env perl use strict; use warnings; use 5.016; for (<DATA>) { chomp; print "Match: $_\n" if /(?=name=bob)(?!flags=.*?cat.*?;)/; } __DATA__ name=bob;flags=human;age=10 name=tiddles;flags=cat,black;age=3 name=bob;flags=cat,white;age=6

My understanding is that this matches if name is set to 'bob' and flags do not contain 'cat' (searching up to the first semicolon). However, it returns both 'bob' lines.

Am I missing something obvious here? I understand that lookaheads are zero-width matches, but maybe this is something to do with anchoring?

PS: I know this could probably be done simpler by splitting on ';' into a hash and validating the hash, but this is a learning exercise :)

Many thanks