Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Regexp to match IP address

by Anonymous Monk
on Aug 06, 2004 at 14:08 UTC ( [id://380550]=perlquestion: print w/replies, xml ) Need Help??

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

I want a quick and easy way to check if a value looks like an IP address, i'm happy just to check if the variable holds 4 numbers separated by dots.

So far I have got

if ($Route=~m/\d\.\d\.\d\.\d/) { do something interesting with the IP address }

Any better way of doing this?

Cheers,Tom

20040808 Edit by castaway: Changed title from 'Perl regexp trickery'

Replies are listed 'Best First'.
Re: Regexp to match IP address
by integral (Hermit) on Aug 06, 2004 at 14:34 UTC

    As well writing a (large) regexp yourself, there's Regexp::Common::net which packages up a regexp for matching ipv4 addresses.

    (It uses a similar regexp to dsb's and mawe's above.)

    --
    integral, resident of freenode's #perl
    
Re: Regexp to match IP address
by mawe (Hermit) on Aug 06, 2004 at 14:28 UTC
    Hi!

    I found this in the Cookbook:
    m/^([01]?\d\d|2[0-4]\d|25[0-5])\.([01]?\d\d|2[0-4]\d|25[0-5])\. ([01]?\d\d|2[0-4]\d|25[0-5])\.([01]?\d\d|2[0-4]\d|25[0-5])$/;
    mawe
      blimey, yeah that'll do it thanks!
      print"\n ip address " if ($s=~/((\d){1,3}\.){3}(\d){1,3}/) ;
Re: Regexp to match IP address
by dsb (Chaplain) on Aug 06, 2004 at 14:31 UTC
    Where's japhy when you need 'em. :)

    I guess it kind of depends on how concerned you are with the validity of your data. Testing for 4 1-3 digit numbers seperated by dots is easy:

    m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\$/;
    If you are interested making sure IP's are valid, you could do a couple of things.

    One, using the above regex, you could grab the digits and test them individually.

    use strict; my @nums; my $IP = "127.0.0.1" (@nums) = $IP =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; # test each for <= 255 here. # also make sure its not 0.0.0.0
    Or you could use a more complicated regex to test for validity during the pattern matching. From O'Reilly's Mastering Regular Expressions:
    m/^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\. ([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$/;
    UPDATE: I just realized this was my 150th post. Yay for me. :)


    dsb
    This @ISA my cool %SIG
      Hi below code validates the IP adress. Please do let me know how this can be enhanced so that it is more readable. The validations considered are listed below. 1) If the length of any part of the IP adress seperated by the decimal is more than one digit, then it should not start with zero. 2) The first part of the IP adress seperated by the decimal cannot be zero. 3) Any part of the IP adress seperated by the decimal cannot be more than 255. 4) IP address should contain only 3 decimals. 5) The numbers cannot be negative. print "Enter the IP address : "; $ip = <stdin>; if($ip =~ /^(3-9\d?|1\d?\d?|2(0-5?0-5?|6-9?))\.(0|3-9\d?|(1\d?\d?|2(0-5?0-5?|6-9?)))\.(0|3-9\d?|(1\d?\d?|2(0-5?0-5?|6-9?)))\.(0|3-9\d?|(1\d?\d?|2(0-5?0-5?|6-9?)))$/) { print "Correct\n"; } else { print "Wrong\n"; }
Re: Regexp to match IP address
by sweetblood (Prior) on Aug 06, 2004 at 14:39 UTC
    consider using Regexp::Common as it has a very complete ip match.

    HTH

    Sweetblood

Re: Regexp to match IP address
by Ven'Tatsu (Deacon) on Aug 06, 2004 at 14:30 UTC
    You have an important error in your code, your only matching 4 digits separated by dots, I think you want /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/ That will match 4 sets of 1 to 3 digits separated by dots.
Re: Regexp to match IP address
by pbeckingham (Parson) on Aug 06, 2004 at 14:33 UTC

    Be aware that your code doesn't do what you think. It checks for 4 single digits separated by periods. \d checks for a single digit, not a number. The code is too simplistic to really check for an IP address.



    pbeckingham - typist, perishable vertebrate.
Re: Regexp to match IP address
by xorl (Deacon) on Aug 06, 2004 at 14:32 UTC
    In this case if it works for you then don't bother to change. You could try
    if ($Route =~ /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/) { # Do stuff }
    As far as I can tell my example isn't any better
Re: Regexp to match IP address
by Prior Nacre V (Hermit) on Aug 06, 2004 at 19:13 UTC

    Or maybe:

    defined((grep { $_ =~ /^\d{1,3}$/ && $_ <= 255 } split /\./, $ip_addr, + 4)[3])
    Update
    Had 127 instead of 225 above

    Regards,

    PN5

      In javascript i did that:
      re=/^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([1-9]|[1-9] +[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}\$/; if(re.test(document.forms[0].ipv4.value)==false){ valid=false; message+="Wrong IP address !\n"; }
      I think it's possible to match the same regexp in perl.

      it seams to work...

      Regards,
      Orion-

        I like this one using quoted reg ex

        my $ip = '192.168.255.254'; # for example # Set up the reg ex my $ipno = qr/ 2(?:5[0-5] | [0-4]\d) | 1\d\d | [1-9]?\d /x; # To test if ( $ip =~ /^($ipno(?:\.|$)){4}/ ){ print "IP OK\n"; };

        I went for an interview at Arm in Cambridge, UK. They asked me to write one on the board and I wrote some lame one .. and later ... brooding on my poor attempt set out to make a better one. Driven by failure? Or maybe just really irritated by it. I still got the job :)

        I haven't used Javascript for 4 or 5 years. Check up-to-date documentation where appropriate.

        I believe Javascript1.3 REs were the same as Perl4's. More recent JS versions may map to more recent Perl versions. However, while the latest version may provide the best solution, consider whether your intended audience will have browsers incorporating the latest JS version.

        Any testing you do on the client side (e.g. Javascript in HTML) must be repeated on the server side (e.g. Perl CGI script). If you can use the same RE in both, this is possibly a good idea for consistency purposes; other considerations may override this.

        I don't think your RE matches 0.n.n.n (from visual inspection). Was this intended? If not, I think you'll need: re=/^([0-9]|...

        Finally, I recall running into difficulties due to differences between JavaScript, JScript and ECMAscript. Something to bear in mind if you're using advanced features.

        Regards,

        PN5

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (2)
As of 2024-04-20 06:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found