http://www.perlmonks.org?node_id=832483


in reply to Determining which pattern matched

There are several ways to achieve this, for example you can use named captures and the %+ hash:
use strict; use warnings; my $pat1 = qr/(?<pat1>field)/; my $pat2 = qr/(?<pat2>f.i.e.l.d)/; my $pat3 = qr/(?<pat3>the)/; my $str = "There are many soccer fields in England - f1i2e3l4d"; while ( $str =~ m/($pat1|$pat2|$pat3)/ig ) { print "Found '$1' from pattern ", keys %+, "\n"; }
Or you can use perl code embedded in regexes:
my $pat_id; my $pat1 = qr/field(?{$pat_id=1})/; my $pat2 = qr/f.i.e.l.d(?{$pat_id=2})/; my $pat3 = qr/the(?{$pat_id=3})/; my $str = "There are many soccer fields in England - f1i2e3l4d"; while ( $str =~ m/($pat1|$pat2|$pat3)/ig ) { print "Found '$1' from pattern pat", $pat_id, "\n"; }
Or you can use the MARK backtracking control verb and the $REGMARK variable:
my $pat_id; our $REGMARK; my $pat1 = qr/field(*MARK:pat1)/; my $pat2 = qr/f.i.e.l.d(*MARK:pat2)/; my $pat3 = qr/the(*MARK:pat3)/; my $str = "There are many soccer fields in England - f1i2e3l4d"; while ( $str =~ m/($pat1|$pat2|$pat3)/ig ) { print "Found '$1' from pattern ", $REGMARK, "\n"; }
Take a look at perlre these are all documented there. For starting I would recommend you the named captures, probably those are the simplest to handle.

Hope this helps.

update: I've just noticed that I changed the meaning of your original match, because I've used precompiled subpatterns. In that case you would like to include the /i modifier in the subpattern itself: qr/the/i

Replies are listed 'Best First'.
Re^2: Determining which pattern matched
by ikegami (Patriarch) on Apr 05, 2010 at 22:23 UTC

    Use local our instead of my for variables declared outside of a (?{}) and (??{}) but used inside of them. It's much safer. Your second snippet won't work if it's moved into a function, for example.

      I've just wanted to demonstrate the technic without much clutter, but you're absolutely right. I should take care to demonstrate the best practice which is using local our instead of my along with (?{ }).

      Here's a great thread explaining the reason behind this for the interested monks (including ikegami's notes): Regexes: finding ALL matches (including overlap).

        My comments in that thread were on an entirely different matter (handling backtracking through (?{}), which isn't an issue in the code here), but blokhead mentioned the issue with lexicals in that thread.