Damien Damien - 9 days ago 4
PHP Question

Combine multiple match regular expression into one and get the matching ones

I have a list of regular expressions:

suresnes|suresne|surenes|surene
pommier|pommiers
^musique$
^(faq|aide)$
^(file )?loss( )?less$
paris
faq <<< this match twice


My use case is that each pattern which got a match display a link to my user,
so I can have multiple pattern matching.

I test thoses patterns against a simple string of text "live in paris" / "faq" / "pom"...

The simple way to do it is to loop over all the patterns with a
preg_match
, but I'm will do that a lot on a performance critical page, so this look bad to me.

Here is what I have tried: combining all thoses expressions into one with group names:

preg_match("@(?P<group1>^(faq|aide|todo|paris)$)|(?P<group2>(paris)$)@im", "paris", $groups);


As you can see, each pattern is grouped:
(?P<GROUPNAME>PATTERN)
and they are all separated by a pipe
|
.

The result is not what I expect, as only the first group matching is returned. Look like when a match occurs the parsing is stopped.

What I want is the list of all the matching groups.
preg_match_all
does not help neither.

Thanks!

Answer

How about:

preg_match("@(?=(?P<group1>^(faq|aide|todo|paris)$))(?=(?P<group2>(paris)$))@im", "paris", $groups);
print_r($groups);

output:

Array
(
    [0] => 
    [group1] => paris
    [1] => paris
    [2] => paris
    [group2] => paris
    [3] => paris
    [4] => paris
)

The (?= ) is called lookahead

Explanation of the regex:

(?=                                     # start lookahead
    (?P<group1>                         # start named group group1
        ^                               # start of string
            (                           # start catpure group #1
                faq|aide|todo|paris     # match any of faq, aide, todo or paris
            )                           # end capture group #1
        $                               # end of string
    )                                   # end of named group group1
)                                       # end of lookahead
(?=                                     # start lookahead
    (?P<group2>                         # start named group group2
            (                           # start catpure group #2
            paris                       # paris
        )                               # end capture group #2
        $                               # end of string
    )                                   # end of named group group2
)                                       # end of lookahead
Comments