I stared with below. It won't fulfill. It can catch ipv4
[\(\d+\.\d+\.\d+\.\d+ \<\)]+
One big character class like this is not the way to match structured substrings. This class is equivalent to [()\d. +<]+ which will match '12345' or '.+.+.+.' or '()(()((()' as well as any dotted decimal IPv4 address, valid or otherwise. Please see perlre and perlretut on the general topic of "character class(es)" (and also perlrecharclass).
The following works (or seems to) for IPv4 dotted decimal addresses only, but it should be fairly easy to extend the $rx_IPv4_dd regex to include IPv6 using the latest Regexp::Common::net. Needs Perl version 5.10+ for the (?|pattern) "branch reset" extension. Needs many more test cases.
c:\@Work\Perl\monks>perl -wMstrict -le
"use 5.010;
;;
use Test::More 'no_plan';
use Test::NoWarnings;
;;
use Regexp::Common qw(net);
;;
my $rx_IPv4_dd = qr{ (?<! \d) $RE{net}{IPv4} (?! \d) }xms;
my $rx_arrow = qr{ \s+ < \s+ }xms;
;;
VECTOR:
for my $ar_vector (
'all these contain one or more IPv4 addresses',
[ 'x (209.85.208.68) x (172.217.194.27 < 123.23.34.45) x',
'209.85.208.68', '172.217.194.27', '123.23.34.45',
],
[ ' < 209.85.208.68) x (172.217.194.27 < 123.23.34.45) x',
'172.217.194.27', '123.23.34.45',
],
[ 'x (1.2.3.4) x (9.8.7.6 < 5.6.7.8) x',
'1.2.3.4', '9.8.7.6', '5.6.7.8',
],
'none of these should match',
[ '', ], [ 'x', ], [ '123', ],
[ '209.85.208.68 (999.12.23.999) (12.23.34.45 98.76.54.32)', ],
) {
if (not ref $ar_vector) {
note $ar_vector;
next VECTOR;
}
;;
my ($str, @expected) = @$ar_vector;
;;
my @got = $str =~ m{
(?|
(?: [(] ($rx_IPv4_dd) (?= (?: $rx_arrow $rx_IPv4_dd)? [)] ) )
|
(?: \G (?! \A) $rx_arrow ($rx_IPv4_dd) [)] )
)
}xmsg;
is_deeply \@got, \@expected, qq{'$str' -> (@expected)};
}
;;
done_testing;
;;
exit;
"
# all these contain one or more IPv4 addresses
ok 1 - 'x (209.85.208.68) x (172.217.194.27 < 123.23.34.45) x' -> (209
+.85.208.68 172.217.194.27 123.23.34.45)
ok 2 - ' < 209.85.208.68) x (172.217.194.27 < 123.23.34.45) x' -> (172
+.217.194.27 123.23.34.45)
ok 3 - 'x (1.2.3.4) x (9.8.7.6 < 5.6.7.8) x' -> (1.2.3.4 9.8.7.6 5.6.7
+.8)
# none of these should match
ok 4 - '' -> ()
ok 5 - 'x' -> ()
ok 6 - '123' -> ()
ok 7 - '209.85.208.68 (999.12.23.999) (12.23.34.45 98.76.54.32)' -> ()
1..7
ok 8 - no warnings
1..8
Give a man a fish: <%-{-{-{-<
|