Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: Determining which pattern matched

by rubasov (Friar)
on Apr 02, 2010 at 13:40 UTC ( #832483=note: print w/ replies, xml ) Need Help??


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


Comment on Re: Determining which pattern matched
Select or Download Code
Re^2: Determining which pattern matched
by ikegami (Pope) 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.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://832483]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (9)
As of 2014-12-20 04:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (95 votes), past polls