Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

How do I match a number range?

by Anonymous Monk
on Nov 28, 2000 at 05:01 UTC ( [id://43580]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question: (regular expressions)

For instance I need a regular expression to identify only those numbers between 5278 to 5391.

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: How do I match a number range?
by Adam (Vicar) on Nov 28, 2000 at 08:25 UTC
    Why use a regular expression?
    my $low = 5278; my $hi = 5391; sub inRange { my $n = shift; return( $hi > $n and $n > $low ); }
Re: How do I match a number range?
by Anonymous Monk on Mar 25, 2001 at 08:29 UTC
    It's probably best to use numeric comparisons, but if you absolutely need a regexp, you can use
    /^5(2(7[89]|[89]\d)|3([0-8]\d|9[01]))$/
Re: How do I match a number range?
by The_Ghost (Acolyte) on Dec 18, 2014 at 23:35 UTC
Re: How do I match a number range?
by quidity (Pilgrim) on Nov 28, 2000 at 05:11 UTC

    This isn't really a regular expression question. You would be better off breaking the task into parts, first to ensure that you have the sort of number you want (for instance, this tests for an integer, and captures it into $1):

    $foo =~ /^(\d+)$/;

    This can then be combined into an if clause:

    if ( $foo =~ /^(\d+)$/ && $1 >= 5278 && $1 <= 5391) { .. }

    although this suffers as you cannot test for 'numberyness' and 'being in the right range' at the same time, to do that, you will need to do it in seperate stages.

    Originally posted as a Categorized Answer.

Re: How do I match a number range?
by extremely (Priest) on Nov 28, 2000 at 06:37 UTC
    Don't. Use the regexp to get the number then do a nice simple numeric compare.
    if ($n >= 5278 and $n <= 5391) { #stuff with $n }

    The regexp is too evil to imagine and writing a general case regexp for when you need to change the numbers is even worse.

    buuuuut... this works if you meant inclusive of 5278 and 5391... /\b5(2([89]\d|7[89])|3([0-8]\d|9[01]))\b/

    Originally posted as a Categorized Answer.

Re: How do I match a number range?
by tye (Sage) on Nov 28, 2000 at 06:06 UTC
    Regular expressions aren't the best tool for finding numbers within a range. However, your range can be broken down into subranges for which regular expressions can be constructed and those can then be combined into a single regular expression:
    5278..5391 5278..5279,5280..5299,5300..5389,5390..5391 /(^|\D)5(2(7[89]|[89]\d)|3([0-8]\d|9[01]))(\D|$)/
    not very pretty and not necessarilly very fast, but it should work.

    tye

    Originally posted as a Categorized Answer.

Re: How do I match a number range?
by japhy (Canon) on Nov 28, 2000 at 05:21 UTC
    The ugly way is to do something like:
    $num =~ m{ \A 5 (?: 2 (?: 7[89] | [89][0-9] ) | 3 (?: [0-8][0-9] | 9[01] ) ) \z }x;
    You can see why I say it's ugly. But it works. I think I could even come up with a range-to-regex converter, for people in such a sad predicament. ;)

    Originally posted as a Categorized Answer.

Re: How do I match a number range?
by chipmunk (Parson) on Nov 28, 2000 at 08:15 UTC
    I think that whether you really want to do this entirely within a regular expression depends on your needs. For example, you could do this:
    if (/(\d{4})/ and $1 >= 5278 and $1 <= 5391) { # do something }
    But that may not meet your requirements. So, you can certainly construct a regex which only matches numbers in that range:
    /5(?:2(?:7[89]|[89][0-9])|3(?:[0-8][0-9]|9[01]))/
    All you need is alternation, and (?:) for precedence.

    Originally posted as a Categorized Answer.

Re: How do I match a number range?
by vroom (His Eminence) on Nov 28, 2000 at 09:57 UTC
    testing

    Originally posted as a Categorized Answer.

Re: How do I match a number range?
by Russ (Deacon) on Nov 30, 2000 at 00:37 UTC
    Less-than-optimally efficient one-liner:
    print 'Yep' if grep {$_ == $Number} 5278..5391;
Re: How do I match a number range?
by cwest (Friar) on Nov 28, 2000 at 05:51 UTC
    my $range = join '|', 5278..5391; my $number = 5300; print "Matched\n" if $range =~ /\b$number\b/;
    --
    Casey
    
      > my $range = join '|', 5278..5391; > my $number = 5300; > print "Matched\n" if $range =~ /\b$number\b/;

      You want $number =~ /^($range)$/ instead.

      Also, you need to create a potentially large list in memory then turn it into a large string. For numbers of this size, this isn't really a problem, but what if you are trying to match unix time values, that's 780k just to match a one day time frame.

        I disagree. If you wanted to see if a number fell within a certain range, then a regex would be a really bad tool to use. However, if you wanted to match all occurances within some larger string of numbers that fell within a certain range, then the pain of using a regex to match a number range might pay off. So I think the original answer was closer to correct than yours. But I think mine is even closer:

        /(^|\D)($range)(\D|$)/
        since the original doesn't find the number in "x5300x".

                - tye (but my friends call me "Tye")
Re: How do I match a number range?
by merlyn (Sage) on Nov 28, 2000 at 08:12 UTC
    Homework?

    If not, please explain why "regular expression" is part of the requirement.

    Originally posted as a Categorized Answer.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (6)
As of 2024-04-24 13:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found