ultranerds has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

This one is puzzling me :/
if ( ($long > 180 || $long < -180) || ($lat > 90 || $lat < -90) || $long !~ /^([\d\-\.]+)$/ || $lat !~ /^([\d\-\.]+)$/ ) { ..show error here }
I'm trying to make sure that the long/lat values pased in only consists of stuff like -4.332423424 , 0, 4.434 , etc

...for some reason, the above code never matchs though. These 2 lines work fine:
($long > 180 || $long < -180) || ($lat > 90 || $lat < -90)
....but the regex stuff never seems to match.

Am I missing something silly? Been working on this for the last 20 mins, and still can't work it out :(

TIA!

Andy

Replies are listed 'Best First'.
Re: Stupid regex question - numerics
by desemondo (Hermit) on Mar 01, 2010 at 11:54 UTC
    The reason is that you're using a character class which says "match at least 1 of anything in the class" so any string with a dot, a digit or a '-' sign in it will match be (incorrectly) satisfied in the in the if ...

    I suspect you are after something a little more forceful:
    $long !~ /^([\-]*[\d]+[\.]*[\d]*)$/ (character classes are only left in for improving readability...)

    This regex says: a leading "-" sign is optional, but must then have at least 1 digit, followed by an optional dot (to cater for cases where $long might equal an integer or 0) followed by optional digits...
      Useless use of square brackets detected! Useless use of backslash detected! Exactly zero of the 8 square brackets in your regexp are needed.1 /^([\-]*[\d]+[\.]*[\d]*)$/ is identical to /^(-*\d+\.*\d*)$/. Furthermore, your regexp also matches -----------------------1.................................. It's doubtful the OP wants to match that. I think you want to use ? in all but one of the cases you wrote *.

      Also note that your regexp doesn't match .123. But it does match ٦৬६.

      1The square brackets don't add anything to the readability. Furthermore, pre-5.10, character classes consisting of a single character are significantly slower than using said character directly (many optimizations won't happen if there's a character class).

      Ah , you legend! Works a charm - thanks :)
Re: Stupid regex question - numerics
by ungalnanban (Pilgrim) on Mar 01, 2010 at 11:58 UTC
    Hi.. your negating the matched patten that is the problem. see the Example.
    my $long =-4.332423424; my $lat = 0; if ( ($long > 180 || $long < -180) || ($lat > 90 || $lat < -90) || $long =~ /^([\d\-\.]+)$/ || $lat =~ /^([\d\-\.]+)$/ ) { print "welcome\n"; }

    Now it matched the condition correctly.
Re: Stupid regex question - numerics
by Fletch (Bishop) on Mar 01, 2010 at 15:04 UTC

    Rather than hand rolling your own (possibly questionable) regex, you might be interested in looks_like_number from the Scalar::Util module which will return true if perl itself would treat the contents as a number.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Stupid regex question - numerics
by ungalnanban (Pilgrim) on Mar 01, 2010 at 12:33 UTC
    See the following code for matching your pattern.
    if ( $long =~ /^([\-\+]?\d+[\.]?\d*)$/ ) { print "match\n"; }
    Thanks.
Re: Stupid regex question - numerics
by ack (Deacon) on Mar 01, 2010 at 21:49 UTC

    JavaFan's answer is definitely my suggestion,too. Only problems is that I'm curious: What about the case of a Lat or Long specified as +1.234 or +0.346? Don't you also want to allow the possibility of a single leading '+' charater?

    Of course you probaby dont want a sigle '+' and a single '-', so that might be case where you'd need a construct something like the following in place of JavaFan's piece -? in his regex:

    (?:+?|-?)

    Where the (?:  ) contruct is used to make it a non-capturing groupimg.

    ack Albuquerque, NM