homepage Welcome to WebmasterWorld Guest from 54.226.43.155
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
Forum Library, Charter, Moderators: coopster & jatar k & phranque

Perl Server Side CGI Scripting Forum

    
perl if elsif control flow
skipping to other parts of an if block
Lts95




msg:3702003
 8:13 pm on Jul 18, 2008 (gmt 0)

I have a perl script parsing access logs and have run into a particular problem

if ($ref =~ m/a/) {
$type = "Type A";
} elsif ($ref =~ m/b/) {
$type = "Type B";
} elsif ($ref =~ m/c/) {
$type = "Type C";
} elsif ($ref =~ m/d/) {
$type = "Type D";
}

My problem is I have some referers that will match to b, but really need to be classified as some other Type further down the if block. I tried to use the next statement but that didn't work.

elsif ($ref =~ m/b/) {
if ($ref =~ m/bc/) {
next;
}
$type = "Type B";
}

Then I tried

elsif ($ref =~ m/b/ && $ref !~ m/bc/) {
$type = "Type B";
}

and that skips the b block correctly, but I have something like bcs that needs to be Type C and bcb that needs to be Type B. So I really need to get something similar to what I was trying with the next statement. Any suggestions?

 

janharders




msg:3702008
 8:16 pm on Jul 18, 2008 (gmt 0)

hm, so /bcs/ should go to C and /bcb/-matches should go to B? is there a general rule for that?
maybe you could go with something like

elsif ($ref =~ m/b/ && $ref !~ m/bc[stmnl]/) {

where stmnl are all the characters that would classify the bc*-thingy as type C?

Lts95




msg:3702029
 8:39 pm on Jul 18, 2008 (gmt 0)

I'm really trying to parse out nested URL query strings. I'd prefer not to hardcode them so my pattern is actually more like /xcode=([^&]+)/ The problem with

elsif ($ref =~ m/xcode=b([^&]+)/ && $ref !~ m/xcode=bc[snmtl][^&]+/) {
$type = "Type B";
}

This results in false positives when the URL has file.html?xcode=b&ycode=2&xcode=bcs&zcode=return In this case the first xcode=b supercedes the second xcode=bcs, but I have no guarantee of what order they will be in. I'd like to avoid creating a list of all valid "b" values but that's starting to look like the simplest solution.

janharders




msg:3702058
 9:04 pm on Jul 18, 2008 (gmt 0)

well, couldn't you do a split on it first, than put it into a hash and query that? that way, you wouldn't have to worry about order, you could just check
if($hash{'bc'} && !$hash{'bc'})

I don't completly understand how you want to build a general rule _without_ letting your script know all the valid values for different types...

perl_diver




msg:3702109
 10:13 pm on Jul 18, 2008 (gmt 0)

I don't understand what you are trying to do.

rocknbil




msg:3702200
 1:59 am on Jul 19, 2008 (gmt 0)

My problem is I have some referers that will match to b, but really need to be classified as some other Type further down the if block.

Note that

1. Presuming you're going through a file (log) in a while loop, next will skip to the next line and ignore any matching on this line completely. So that won't work.

2. if/elsif can catch you in exactly these circumstances. Since you catch the first condition in an elsif, it's gong to ignore anything after. Right?

So, maybe a simple workaround is to not use elsif at all, just a series of if's. You have to use caution when you do this, as later if's will overwrite previous ones, which sounds like what you want to do.

$string = 'aaaabccc';

if ($string =~ /a/) { $letter = 'A'; }
if ($string =~ /b/) { $letter = 'B'; }
if ($string =~ /c/) { $letter = 'C'; }

print $letter;

So at first, $letter is A, but it gets overwritten and becomes B, then in the third match becomes C. You may want more complex if's further down:


if ($string =~ /a/) { $letter = 'A'; }
if ($string =~ /b/) {
$letter = ($string =~ /a/)?'both A and B':'B';
}
if ($string =~ /c/) {
$letter = ($string =~ /[ab]/)?'Contains A or B, and C':'C';
}

As always, TMTOWTDI in Perl. :-)

phranque




msg:3702252
 6:18 am on Jul 19, 2008 (gmt 0)

as a rule you should put your most specific tests first and the more general tests later.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved