if ( my (@caps) = ($line =~ $re) ) { @caps = () if $caps[0] ne $1; # reset pseudo captures $cb->(@caps); last; } #### c:\@Work\Perl\monks>perl use strict; use warnings; use Data::Dump qw(pp); my $cb = sub { print "matched, captured ", pp @_; }; for my $str ("AB","") { for my $re (qr/../, qr/(.)(.)/, qr/(X)?(.)/, qr/XY/, qr/(X)Y/, qr//) { print "str <$str> re $re "; if ( my (@caps) = ($str =~ $re) ) { # @caps = () if $caps[0] ne $1; # reset pseudo capture $#caps = $#- - 1; # reset pseudo capture $cb->(@caps); } else { print 'NO match'; } print "\n"; } } ^Z str re (?-xism:..) matched, captured () str re (?-xism:(.)(.)) matched, captured ("A", "B") str re (?-xism:(X)?(.)) matched, captured (undef, "A") str re (?-xism:XY) NO match str re (?-xism:(X)Y) NO match str re (?-xism:) matched, captured () str <> re (?-xism:..) NO match str <> re (?-xism:(.)(.)) NO match str <> re (?-xism:(X)?(.)) NO match str <> re (?-xism:XY) NO match str <> re (?-xism:(X)Y) NO match str <> re (?-xism:) matched, captured ()