Further to Discipulus's post: Note
that $RE{net}{IPv4} from Regexp::Common (in
common with many
patterns in this family of modules) intentionally has no boundary
assertions; these are left to the programmer and are determined by the
exact end-use of the pattern. So 999.9.9.999 will have
99.9.9.99 extracted from it as a valid IP if no bounds are
specified.
Were one extracting IPs from a string, one might do something like
this:
Win8 Strawberry 5.30.3.1 (64) Fri 01/29/2021 22:12:11
C:\@Work\Perl\monks
>perl -Mstrict -Mwarnings
use Regexp::Common;
my $rx_extract_ipv4 = qr{ (?<! \d) $RE{net}{IPv4} (?! \d) }xms;
for my $s (
'1.2.3.4foo11.22.33.44bar111.222.233.244 0.0.0.0 .255.255.255.255.
+',
'999.9.9.999 256.255.255.256',
) {
my @ips = $s =~ m{ $rx_extract_ipv4 }xmsg;
printf "'$s' \n -> (%s) \n\n", join ' ', map "'$_'", @ips;
}
^Z
'1.2.3.4foo11.22.33.44bar111.222.233.244 0.0.0.0 .255.255.255.255.'
-> ('1.2.3.4' '11.22.33.44' '111.222.233.244' '0.0.0.0' '255.255.255
+.255')
'999.9.9.999 256.255.255.256'
-> ()
A roll-your-own approach to extracting decimal octet IPv4s might be:
Win8 Strawberry 5.8.9.5 (32) Fri 01/29/2021 22:22:11
C:\@Work\Perl\monks
>perl -Mstrict -Mwarnings
my $rx_dec_octet = qr{ 25[0-5] | 2[0-4]\d | [01]? \d \d? }xms
+;
my $rx_ipv4 = qr{ $rx_dec_octet (?: [.] $rx_dec_octet){3} }xms
+;
my $rx_extract_ipv4 = qr{ (?<! \d) $rx_ipv4 (?! \d) }xms
+;
for my $s (
'1.2.3.4foo11.22.33.44bar111.222.233.244 0.0.0.0 .255.255.255.255.
+',
'999.9.9.999 256.255.255.256',
) {
my @ips = $s =~ m{ $rx_extract_ipv4 }xmsg;
printf "'$s' \n -> (%s) \n\n", join ' ', map "'$_'", @ips;
}
^Z
'1.2.3.4foo11.22.33.44bar111.222.233.244 0.0.0.0 .255.255.255.255.'
-> ('1.2.3.4' '11.22.33.44' '111.222.233.244' '0.0.0.0' '255.255.255
+.255')
'999.9.9.999 256.255.255.256'
-> ()
Of course, it's up to the programmer to chose boundary
assertions appropriate to the string extraction context.
(And lots of testing is a good idea, too. :)
Update: Minor wording changes.
Give a man a fish: <%-{-{-{-<
|