Wednesday, April 16, 2008

perl: matching an IPv4 address

SOLUTION 1: Jeffrey Friedl's "Mastering Regular Expressions"
source

my $ReIpNum = qr{([01]?\d\d?|2[0-4]\d|25[0-5])};
my $ReIpAddr = qr{^$ReIpNum\.$ReIpNum\.$ReIpNum\.$ReIpNum$};

my %ips = ('0.0.0.0' => 1,
           '1.2.3.4' => 1,
           '255.255.255.255' => 1,
           '000.34.2000.2' => 0,
           '' => 0,
           '24.23.23.' => 0);

for my $ip(keys %ips) {
    die "Failed: $ip"
    unless (($ip =~ m{$ReIpAddr}) == $ips{$ip});
    print "$ip passed\n";
}




SOLUTION 2: USE Regexp::Common
source
#!/bin/perl
use Regexp::Common;

while() {
    if(/$RE{net}{IPv4}{dec}{-keep}/) {
        print "IP Address: $1\n";
    }
}

__DATA__
24.113.50.245
0.42.523.2
255.242.52.4
2.5.3





Discussion:

IP addresses are difficult to match using a simple regular expression, because the regular expression must verify that the IP address against which it is matching is valid. A simple expression such as /\d{3}\.\d{3}\.\d{3}\.\d{3}/ will incorrectly match strings such as 789.23.2.900, which is outside the range of valid IP addresses (i.e., 0.0.0.0 to 255.255.255.255). Damian Conway's Regexp::Common module provides a very effective regular expression which matches only valid IP addresses.

No comments: