Dies ist ein Follow-up von . Ich wollte zeigen, wie ich das Problem richtig lösen kann, aber ich habe ein unerwartetes Verhalten gezeigt.Wie kommt es, dass diese Regex nicht gierig ist?
use 5.010;
use strictures;
use Data::Munge qw(list2re);
use Regexp::IPv6 qw($IPv6_re);
use Regexp::Common qw(net);
our $port_re = list2re 0..65535;
sub ip_port_from_netloc {
my ($sentence) = @_;
return $sentence =~/
( # capture either
(?<= \[)
$IPv6_re # IPv6 address without brackets
(?= \])
| # or
$RE{net}{IPv4} # IPv4 address
)
: # colon sep. host from port
($port_re) # capture port
/msx;
}
my ($ip, $port);
($ip, $port) = ip_port_from_netloc 'The netloc is 216.108.225.236:60099';
say $ip;
($ip, $port) = ip_port_from_netloc 'The netloc is [fe80::226:5eff:fe1e:dfbe]:60099';
say $ip;
Die zweite Übereinstimmung schlägt fehl. use re 'debugcolor'
zeigt, dass :($port_re)
bereits innerhalb der IPv6-Adresse :5
entspricht. Das überrascht mich, weil ich die Gier mit einem ?
nicht ausgeschaltet habe. Ich habe damit gerechnet, dass alles bis auf die ]
verschlungen wird, nur dann gegen den Trenndoppelpunkt und was danach folgt.
Warum passiert das, und was ist das Heilmittel?
Und noch eine verrückte Möglichkeit: Halte die Klammer im Lookahead und benutze '(? (2) \ 2)' nach dem Capture. Ich muss allerdings ein Listen-Slice für das Match-Ergebnis verwenden ('(...) [0,2]'). – ikegami
Oh, wow, named Capture-Gruppen sind sicher hübsch! –
@Richard Simões, Eingeführt in 5.10, IIRC, zusammen mit ein paar anderen Dingen. – ikegami