hello fellow monks,

some days ago I was playing with an "advanced search"-like form, one of these where you can fill one or more search fields. something like:

# example of form: # Name: __________ # Address: __________ # Telephone: __________ # etc. # [Search]
of course, some of the fields could be blank. the searching code, reduced to its minimum, was something like:
if( $name =~ /\Q$pattern_name\E/i and $address =~ /\Q$pattern_address\E/i and $telephone =~ /\Q$pattern_telephone\E/i) { print "matched\n"; }
the match mysteriously failed when filling just the "Name" field, and I was puzzled for a few hours before finding out what was wrong.

the bug is really subtle indeed, and if you can spot it at a first glance, ++ to you.

what happens here is that, if one of the $pattern variables are blank, the regexp pattern evaluates to the empty string, and guess what this means? the last successfully matched regular expression is used instead. and more, if no match has previously succeeded, this will (silently) act instead as a genuine empty pattern (which will always match). (the italic is taken from perlop).

so, if I put, for example "da" in the "Name" field, my if statement tries to match name, address AND telephone from my database with "da". and this obviously fails. even putting debug statements outside the if, just to check what I thought was matched (eg. print the pattern, print the result of $data =~ /pattern/) didn't help, because it's the order of the matches that screw things up.

I ended up changing my code to something like:

if( (not $pattern_name or $name =~ /\Q$pattern_name\E/i) and (not $pattern_address or $address =~ /\Q$pattern_address\E/i) and (not $pattern_telephone or $telephone =~ /\Q$pattern_telephone\E/i +) ) { print "matched\n"; }
(I know, I could I've just used index instead of a regexp in this case, but the principle still applies).

and what I've learned is: something like /$pattern/ (I mean, just a variable inside a regexp and nothing else) is probably a bad idea, unless you're really, really sure that $pattern will actually contain something.

I hope this word of warning could save some headache to someone else in the future :-)

cheers,
Aldo

King of Laziness, Wizard of Impatience, Lord of Hubris


In reply to a word of warning about /$pattern/ by dada

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.