4

我有一个正则表达式列表:

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

我的用例是每个匹配的模式都显示一个指向我的用户的链接,所以我可以有多个模式匹配。

我用一个简单的文本字符串“live in paris”/“faq”/“pom”来测试这些模式......

最简单的方法是用 a 遍历所有模式preg_match,但我会在性能关键页面上做很多事情,所以这对我来说看起来很糟糕

这是我尝试过的:将所有这些表达式与组名组合成一个:

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

正如你所看到的,每个模式都是分组的:(?P<GROUPNAME>PATTERN)它们都由一个管道分隔|

结果不是我所期望的,因为只返回了第一个组匹配。看起来当匹配发生时解析停止。

我想要的是所有匹配组的列表。preg_match_all也无济于事。

谢谢!

4

3 回答 3

7

怎么样:

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

输出:

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

(?= )被称为前瞻

正则表达式的解释:

(?=                                     # 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
于 2013-04-25T11:26:22.827 回答
1

试试这个方法:

#/ define input string
$str_1 = "{STRING HERE}";

#/ Define regex array
$reg_arr = array(
'suresnes|suresne|surenes|surene',
'pommier|pommiers',
'^musique$',
'^(faq|aide)$',
'^(file )?loss( )?less$',
'paris',
'faq'
);

#/ define a callback function to process Regex array
function cb_reg($reg_t)
{
    global $str_1;
    if(preg_match("/{$reg_t}/ims", $str_1, $matches)){
    return $matches[1]; //replace regex pattern with the result of matching is the key trick here
    //or return $matches[0]; if you dont want to get captured parenthesized subpatterns
    //or you could return an array of both. its up to you how to do it.
    }else{
    return '';
    }
}

#/ Apply array Regex via much faster function (instead of a loop)
$results = array_map('cb_reg', $reg_arr); //returns regex results
$results = array_diff($results, array('')); //remove empty values returned

基本上,这是我能想到的最快的方法。

  1. 您不能将 100 多个正则表达式组合到一个调用中,因为它会是非常复杂的正则表达式,并且有几次匹配失败的机会。这是最好的方法之一。

  2. 在我看来,与onpreg_match的这种方法相比,将大量正则表达式组合成 1 个正则表达式(如果可能实现)会更慢执行。请记住,这里的关键是,这是为您和类似情况处理数组的最快方法。CallbackArraysCallback function on array member valuesphp

另请注意, Thecallback on Array不等于looping the Array。循环速度较慢,并且从算法分析中得到一个n 。但是数组元素的回调是内部的,相比之下非常快。

于 2013-04-24T20:58:56.397 回答
0

您可以将所有正则表达式与“|”结合起来 在他们之间。然后应用这个:http://www.rexegg.com/regex-optimizations.html,它将优化它,折叠常用表达式等。

于 2016-11-23T21:51:58.613 回答