There have been a number of pages around T'internet on regexps for determining an IP number, and I needed a slight variation.... which has led me to a really natty regexp for the base use-case:

chomp $ip; my $quad = '([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'; if ($string =~ /^(${quad}\.){3}${quad}$/) { ## have valid IP }

All previous examples have been long strings defining each quad separately... I use two simple tricks:

  1. use variable substitution for the actual pattern, and
  2. use the repeat operator to define three repeats of the first section

oh... and ${quad} is just a way of ensuring that the right variable name is used... a-la $foo = "${bar}barella" looks for $bar and appends barella to it


In my case, I wanted to try to guess between a (partial) IP number, a hostname, or some other string (a name) - so I have:

# $q contains the string to test my $quad = '([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'; given ($q) { when ( # Is it an IP? # matches 127 or 127. or 127.0 or 127.0. or... # does not match any quad above 255, or 127.0.0.1. # as the fifth dot fails the match /^((${quad}\.){0,2}${quad}\.?|(${quad}\.){3}${quad})$/ ) { $type = 'ip'; } ## end when ( ...) when (/\w+\.\w+/) { # Is it a domain name? # words.words $type = 'url' } default { $type = 'name' } # it must be a name then... } ## end given


-- Ian Stuart
A man depriving some poor village, somewhere, of a first-class idiot.

Replies are listed 'Best First'.
Re: Checking for a valid IP number
by rustic (Monk) on Jun 11, 2012 at 13:07 UTC
    Another approach, to do the hard job will be
    use Data::Validate::IP qw(is_ipv4);
    which has also a nice way to validate a domain
    use Data::Validate::Domain qw(is_domain);
    and email
    use Data::Validate::Email qw(is_email);
Re: Checking for a valid IP number
by mbethke (Hermit) on Jun 30, 2012 at 19:41 UTC
    This is really reinventing the wheel considering there are tons of ready-made solutions for this everyday task. If you do need a variation not covered by these, I'd suggest adding /o to the regexp to have it compile the whole length thing only once.