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

php, preg-match, regex

Solution

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

Problem

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!

Original source