On further investigation, it appears GrandFather's solution, as corrected by nmerriweather, is correct. ikegami's solution passes a 1 into @captures in the case of a successful match with no captures requested. This doesn't DWIM, and it proved to be a deal-breaker in my real-world task.
my $line = q{Convention_9841_12345678901234.txt};
my @captures;
print "\nIncorrect\n\n";
print_captures( incorrect( qr/Convention_(\d{4})_(\d{14})\.txt$/, $lin
+e ) );
print_captures( incorrect( qr/Convention_(\d{4})_\d{14}\.txt$/, $line
+) );
print_captures( incorrect( qr/Convention_\d{4}_\d{14}\.txt$/, $line )
+);
print_captures( incorrect( qr/Convention_((\d{4})_(\d{14}))\.txt$/, $l
+ine ) );
print_captures( incorrect( qr/^(.*Convention_(\d{4})_(\d{14})\.txt)$/,
+ $line ) );
print "\nCorrect\n\n";
print_captures( get_captures( qr/Convention_(\d{4})_(\d{14})\.txt$/, $
+line ) );
print_captures( get_captures( qr/Convention_(\d{4})_\d{14}\.txt$/, $li
+ne ) );
print_captures( get_captures( qr/Convention_\d{4}_\d{14}\.txt$/, $line
+ ) );
print_captures( get_captures( qr/Convention_((\d{4})_(\d{14}))\.txt$/,
+ $line ) );
print_captures( get_captures( qr/^(.*Convention_(\d{4})_(\d{14})\.txt)
+$/, $line ) );
sub incorrect {
my ($pattern, $line) = @_;
my @captures;
(@captures) = $line =~ m/$pattern/ or return;
return @captures;
}
sub get_captures {
my ($pattern, $line) = @_;
$line =~ m/$pattern/ or return;
return map {substr $line, $-[$_], $+[$_] - $-[$_]} (1 .. $#-);
}
sub print_captures {
my @captures = @_;
@captures ? print "captures: @captures\n" : print "no captures\n"
+;
}
| [reply] [d/l] [select] |
sub get_captures {
my ($pattern, $line) = @_;
my @captures = $line =~ m/$pattern/;
shift(@captures) if !$#+;
return @captures;
}
or
sub get_captures {
my ($pattern, $line) = @_;
my @captures = $line =~ m/($pattern)/;
shift(@captures);
return @captures;
}
| [reply] [d/l] [select] |
The second example you showed ...
sub get_captures {
my ($pattern, $line) = @_;
my @captures = $line =~ m/($pattern)/;
shift(@captures);
return @captures;
}
... won't work in the production code of which my code presented here is a sample. That's because it would impose upon my users an unnecessary and likely-to-be-forgotten requirement: that they enclose the regex in parentheses so as to guarantee that at least one substring is captured.
More interesting is this approach, which you tucked away:
sub get_captures {
my ($pattern, $line) = @_;
my @captures = $line =~ m/$pattern/;
return @captures[0 .. $#+ - 1];
}
Once I understand @+ and @- better, I'll see whether I like this better than Grandfather's suggestion.
Thank you very much.
| [reply] [d/l] [select] |