Operating System - HP-UX
1753946 Members
7724 Online
108811 Solutions
New Discussion

Perl : Numeric Range Pattern Matching

 
SOLVED
Go to solution
doubando
Frequent Advisor

Perl : Numeric Range Pattern Matching

hi Experts

 

just wondering if you can help me if i want to check a number between specific range

 

if i have an ip address , how can i say the valid number for ip between 1 to 254

 

something like this

 

if ($ip ) =~ /[1-254].[1-254].[1-254].[1-254]/

   {

      

  }

 

thanks

6 REPLIES 6
donna hofmeister
Trusted Contributor

Re: Perl : Numeric Range Pattern Matching

Probably...have you tested it??

 

you made no statement regarding the cleanliness of your data, so it's difficult to impossible to know how to answer your question.  are you always going to have IPv4 format addresses?  what about netmasks?  what about some the of "exception" IP addresses?

 

if your want to rigorously test your IP address, i suggest you install NetAddr::IP.

 

to take a peek at a conversation were this question was already asked, head over to perlmonks.

James R. Ferguson
Acclaimed Contributor
Solution

Re: Perl : Numeric Range Pattern Matching

Hi:

 

There are a number of things wrong with your approach.

 

1.  A dot character will match anything, so you need to escape it.

2.  Character class ranges are single ranges from first to the second single character.

3.  You should anchor your match to avoid false matches as with a string that began with "1234.".

 

In all, there is a better alternative to rolling your own in this case:  'Regexp::Common:net'.

 

Consider this example:

 

# cat ./verifyip

#!/usr/bin/perl
use strict;
use warnings;
use Regexp::Common qw( net );
while (<>) {
    chomp;
    if ( /^$RE{net}{IPv4}$/ ) {
        print "$_ is valid\n";
    }
    else {
        print "$_ is not a valid IPv4 address\n";
    }
}
1;

Regards!

 

...JRF...

James R. Ferguson
Acclaimed Contributor

Re: Perl : Numeric Range Pattern Matching

Hi (again):

 

I'm happy to have helped.  Since this community is new, replacing the former ITRC, please read:

 

http://h30499.www3.hp.com/t5/help/faqpage/faq-category-id/kudos#kudos

 

Regards!

 

...JRF...

Dennis Handly
Acclaimed Contributor

Re: Perl : Numeric Range Pattern Matching

Basically you can't check ranges, only patterns.  To exclude 0 and 255, you would have to do extra work.

It might be easier to crack the 4 numeric values and then do a numeric range check.

Hein van den Heuvel
Honored Contributor

Re: Perl : Numeric Range Pattern Matching

>>>  /[1-254].[1-254].[1-254].[1-254]/

 

James had the nice solution. And I'm pleased you marked his reply as 'solved'.

[ You seem to have forgotten the 'kudo', so I gave one just in case. Feel free to add more. ]

 

If under certain circumstanses still want to use a simple regular expression match,

then you can at most do something like:

 

/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/

 

So this just looks for a pattern with 1 to 3  numbers, a dot, 1 to 3 numbers and other dot and so on.

The \b requests a 'boundary', like a word, or begin of end of line.

The leading \b fill fails patterns like   test1.2.3.4

and the trailing \b stops patterns like 1.2.3.4test

The test above incorrectly fails 0123.2.3.4 which is legal, but that serves 'm right imho.

It does NOT check the 255 range though.

 

Cheers,

Hein

 

 

James R. Ferguson
Acclaimed Contributor

Re: Perl : Numeric Range Pattern Matching

Hi (again):

 

In the spiril of TIMTOWTDI , you could write:

 

if ( m/^(?:\d{1,3}[.]){3}\d{1,3}$/ ) {

 ...which says:

 

Match, but don't capture (because we don't need to and its faster than capturing) three repetions of one-to-three digits anchored to the beginning of the field or line being matched:

 

^(?:\d{1,3}

 

...followed by a dot:

 

[.]

 

...and do this three times:

){3}

 

...followed by a digit one-to-three times, anchored to the end of the line or field:

 

\d{1,3}$

 

The downside, as I originally hinted, if you played a bit with the use of 'Regexp::Common::net', is that the Perl module would *not* consider an address like this to be valid:

 

999.888.777.666

 

Regards!

 

...JRF...