harangzsolt33 has asked for the wisdom of the Perl Monks concerning the following question:

I feel like I have learned a lot in the past 10 years since I started learning Perl, but I still probably don't know more than half of what's possible using regex. I have often come across situations where I needed to identify which pattern occurs first in a string. So, I am not trying to capture a part of the pattern nor am I trying to identify if it occurs at all or where. I am just trying to figure our which of the possible patterns is FIRST in the string. For example:

Sample string: "AB ABDA DCACCB AAA BSAA CAAB ACS ABA DBA BA DASSABACA +A" I'm looking for either: BA[ABC]{2} OR CA[CD]{2} OR DA[SC]{2} So, I would write: /BA[ABC]{2}|CA[CD]{2}|DA[SC]{2}/

Is there a way to get a return value of 1, 2, or 3 depending on which pattern was matched first? How would I do that?

Replies are listed 'Best First'.
Re: Regex question - identify which pattern comes first
by ikegami (Patriarch) on May 02, 2026 at 01:53 UTC
    if ( /(BA[ABC]{2})|(CA[CD]{2})|(DA[SC]{2})/ ) { my $first = ( defined( $1 ) ? 1 : defined( $2 ) ? 2 : 3 ); ... }
    local our $first; / (?: BA[ABC]{2} (?{ $first = 1; }) | CA[CD]{2} (?{ $first = 2; }) | DA[SC]{2} (?{ $first = 3; }) /x;

    Update: I had mixed up (??{ }) and (?{ }). Fixed.

      Oh wow, that is an amazingly simple solution! Thank you so much!!! :-)
        > that is an amazingly simple solution!

        Did you try it?

        These (??{ $first = 1; }) won't work because they'll include 1,2 or 3 into the regex.

        Try (?{ $first = 1; }); with a single ? instead.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        see Wikisyntax for the Monastery

        Thus
Re: Regex question - identify which pattern comes first (named captures)
by LanX (Saint) on May 02, 2026 at 15:18 UTC
    requires 5.10 for named capture groups:

    This code will even give you the sequence.

    use v5.10; use strict; use warnings; my $str = "AB ABDA DCACCB AAA BSAA CAAB ACS ABA DBA BA DASSABACA A"; while ( $str =~ / (?<_1> BA[ABC]{2} ) | (?<_2> CA[CD]{2} ) | (?<_3> DA +[SC]{2} ) /gx) { print keys %+, " => ", values %+, " at pos ", pos($str), " \n"; }

    _2 => CACC at pos 13 _3 => DASS at pos 48 _1 => BACA at pos 53

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

    edit

  • inserted /x for readability

      Adjusted for OP:

      if ( $str =~ / (?: (?<_1> BA[ABC]{2} ) | (?<_2> CA[CD]{2} ) | (?<_3> DA[SC]{2} ) /x ) { my $first = substr( ( keys( %+ ) )[0], 1 ); ... }