Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Expression, but is it regular?

by web-yogini (Novice)
on May 08, 2001 at 15:11 UTC ( #78791=perlquestion: print w/ replies, xml ) Need Help??
web-yogini has asked for the wisdom of the Perl Monks concerning the following question:

I am so lost with this! Can anyone help? We have a big mail system that is broken down in subdirectories such as an/andy or bo/bobby and this string is supposed to find *only* letters, and if not letters.. to use the $dirtype of "other" instead. It's not working... any ideas?
$dirtype = $1 || 'other' if($in{username} =~ /^(\[a-zA-Z]{2})/ || ' ') +;

Comment on Expression, but is it regular?
Download Code
Re: Expression, but is it regular?
by OeufMayo (Curate) on May 08, 2001 at 15:19 UTC

    You're probably looking for something like that:

    my $dirtype = $in{username} =~ /^([a-zA-Z]{2})$/ ? $1 : 'other' ;

    <kbd>--
    my $OeufMayo = new PerlMonger::Paris({http => 'paris.mongueurs.net'});</kbd>
Re: Expression, but is it regular?
by srawls (Friar) on May 08, 2001 at 15:26 UTC
    The reason I suspect that your regex isn't working is that you have a phantom slash, it is escaping the [ character, thus making it a literal.

    The 15 year old, freshman programmer,
    Stephen Rawls
Re: Expression, but is it regular?
by Trimbach (Curate) on May 08, 2001 at 16:13 UTC
    OeufMayo is exactly correct, but just to add a little detail regarding your logic: here's your code rearranged into a more traditional format:
    if ($in{username} =~ /^(\[a-zA-Z]{2})/ || ' ') { $dirtype = $1 || 'other'; }
    First of all, the "or" in the "if" statement will never trigger because "if" always tests for "truth." In other words, the "if" is saying "if the regular expression is true OR the string " " is true." Unfortunately, " "is NEVER true in Perl, so if your regex doesn't match the if is skipped entirely.

    Second of all, IF the regular expression DOES match (triggering the code between the brackets and populating $1 at the same time) THEN in your case $1 is always guaranteed to be true (because it will contain two A-Za-z letters. Letters always evaluate to "true." Because the first expression in your short-circuit operation ($1) is always true, your program will never get to the 'other' value.

    This is why OeufMayo resorted to a ternary operator, which is just a short-hand way to write another if/then statement. Here it is rewritten for clarity:

    my $dirtype; if ( $in{username} =~ /^([a-zA-Z]{2})$/ ) { $dirtype = $1; } else { $dirtype = 'other'; }
    This way the logic is all straigthened out.

    And then there's the backslash in your regex. :-D

    Gary Blackburn
    Trained Killer

      You were right the second time. That is a good way to explain things. Usually it is best to start out with a multi-line piece of code, rather than trying to write a very complex one liner. It is easier to debug the multi-line piece and then simplify it down into a one liner.

      One clarification... (Unfortunately, " "is NEVER true in Perl)... There are some things that are true that you wouldn't think are true (in this case " " actually is). Try some of the following...
      perl -e 'print "1\n" if "";' perl -e 'print "1\n" if " ";' perl -e '@a=(); print "1\n" if @a;' perl -e '@a=(undef); print "1\n" if @a;'

      Empty strings and empty lists do evaluate to false. Strings and lists with even one item evaluate to true, even if that one item is itself false.

      my @a=qw(random brilliant braindead); print $a[rand(@a)];
      Thank you so much for the excellent logic lesson. I stripped it apart like you suggested, and now it is working wonderfully.

      Thanks again for all the responses! You Perl Monks are such enlightened brethren! ; )

      Sad Gurunath Maharaj ki jai!
Re: Expression, but is it regular?
by novitiate (Scribe) on May 08, 2001 at 19:32 UTC
    Are we not also trying to test for the ' ' empty string here? I'm a little confused, the fixup code doesn't seem to address this - i guess you could add the empty string test to your regex, then you will evaluate an a-zA-Z{2} and an ' ' to true and execute the true branch.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://78791]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (17)
As of 2014-07-14 10:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (257 votes), past polls