Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Range Issue with RegEx

by Anonymous Monk
on Jul 10, 2006 at 14:08 UTC ( #560144=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Folks, I am trying to capture entries with a specific digit range. I am trying the code below but it's generating the following:
500 501 502 503 504 508 522 531 532 505
I just want to capture 500, 501, 502, 531, 532 Any ideas how to achive this using the range symbol? Thanks.
while (<DATA>){ chomp; $tag = $_; #if ($tag =~ /50[0-2]/ || $tag =~ /5[30-33]/){ if ($tag =~ /50[0-2]|5[30-33]/){ print "$tag\n"; } } __DATA__ 500 501 502 503 504 508 522 531 532 547 548 555 444 505

Replies are listed 'Best First'.
Re: Range Issue with RegEx
by liverpole (Monsignor) on Jul 10, 2006 at 14:19 UTC
    There are a few problems in your code:

    First of all, [30-33] does NOT match 30, 31, 32; it matches any of the single characters 3, 0 - 3, 3, which is the same as [0-3].  (The expression [...] is a character class, meaning that it matches only a single character).

    Secondly, when you do /50[0-2]|5[30-33]/, you are trying to match 4 characters in a row:  5, 0, 0-2 or 5, 0-3.

    I think what you want instead is:

    if ($tag =~ /^(50[0-2])|(53[0-2])$/)

    or more simply:

    if ($tag =~ /^(50|53)[0-2]$/)

    or even:

    if ($tag =~ /^5(0|3)[0-2]$/) # Note the parentheses ( ) are optiona +l

    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: Range Issue with RegEx
by VSarkiss (Monsignor) on Jul 10, 2006 at 15:59 UTC
Re: Range Issue with RegEx
by ptum (Priest) on Jul 10, 2006 at 14:35 UTC

    And of course, if you're strictly dealing with numerical data, you don't necessarily have to mess around with a regex -- you might be able to select the numbers you want based on a mathematical rule, as in this (untested) snippet:

    while (<DATA>) { my $tag = $_; if (($tag % 10) < 3) { print "$tag\n"; } }

    No good deed goes unpunished. -- (attributed to) Oscar Wilde
Re: Range Issue with RegEx
by grinder (Bishop) on Jul 10, 2006 at 16:19 UTC
    I just want to capture 500, 501, 502, 531, 532

    Currently you want to do something like /5(?:0[012]|3[12])/, although in the development version of Perl, which will one day be released as 5.10, you are better off (thanks to the work of Yves Orton) by just listing the alternations, and let the regexp engine build a trie out of the alternatives: /500|501|502|531|532/. This is fast.

    • another intruder with the mooring in the heart of the Perl

Re: Range Issue with RegEx
by TedPride (Priest) on Jul 10, 2006 at 18:36 UTC
    Or create a hash lookup for your range and then compare it to the numbers. This is probably the best method if your data file is very large and/or your range is large.
    $h{$_} = () for (500, 501, 502, 531, 532); while (<DATA>) { chomp; print "$_\n" if exists $h{$_}; } __DATA__ 500 501 502 503 504 508 522 531 532 505

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2018-11-14 06:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My code is most likely broken because:
















    Results (163 votes). Check out past polls.

    Notices?