Php 将多个匹配正则表达式组合成一个,并获得匹配的正则表达式

Php 将多个匹配正则表达式组合成一个,并获得匹配的正则表达式,php,regex,preg-match,Php,Regex,Preg Match,我有一个正则表达式列表: suresnes|suresne|surenes|surene pommier|pommiers ^musique$ ^(faq|aide)$ ^(file )?loss( )?less$ paris faq <<< this match twice 如您所见,每个模式都是分组的:(?PPATTERN),它们都由管道|隔开 结果不是我所期望的,因为只返回第一个组匹配。看起来,当匹配发生时,解析

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

suresnes|suresne|surenes|surene
pommier|pommiers
^musique$
^(faq|aide)$
^(file )?loss( )?less$
paris
faq                              <<< this match twice
如您所见,每个模式都是分组的:
(?PPATTERN)
,它们都由管道
|
隔开

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

我想要的是所有匹配组的列表
preg\u match\u all
也没有帮助

谢谢

试试这种方法:

#/ 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
基本上,这是我能想到的最快的方法

  • 您不能将100个Regex组合到一个调用中,因为构建Regex将非常复杂,并且有几次匹配失败。这是最好的方法之一

  • 在我看来,将大量正则表达式组合成一个正则表达式(如果可能的话)与
    preg_match
    相比,使用
    Callback
    数组上执行
    要慢一些。请记住,这里的关键是
    数组成员值回调函数
    ,这是在
    php
    中处理数组和类似情况的最快方法

  • 还注意到, 数组上的
    回调
    不等于
    循环数组
    。循环速度较慢,并且从算法分析中有一个n。但是数组元素的回调是内部的,与之相比非常快。

    怎么样:

    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
    
    (?=#开始前瞻
    (?P#启动命名组group1
    ^#字符串开头
    (#启动catpure组#1
    常见问题解答|助手|待办事项|巴黎|匹配任何常见问题解答、助手、待办事项或巴黎
    )#终端捕获组#1
    $#字符串末尾
    )#命名组group1的结尾
    )#展望结束
    (?=#开始向前看
    (?P#启动命名组group2
    (#启动catpure group#2
    巴黎#巴黎
    )#终端捕获组#2
    $#字符串末尾
    )#命名组group2的结尾
    )#展望结束
    
    您可以将所有正则表达式与它们之间的“|”组合起来。然后应用此:,它将优化它,折叠常见表达式,等等。

    “我想要的是所有匹配组的列表。”
    preg\u match\u all
    为您提供每个匹配的捕获组列表。我已经尝试过,只有第一个组返回匹配。
    $groups[0]
    应包含与匹配列表等效的数组<代码>$groups['group1']
    将包含一个长度与第一组匹配项相同的列表。第二组也一样。经过测试,它是有效的。另外,如果您关心性能,请检查。Damien是对的,我看不到任何使用
    preg\u match\u all
    来实现这一点的简单方法,因为它将仅为第一个匹配组返回匹配。这是在输入字符串的所有字符上运行所有regexp,这很快,而且很有效(我有这样的实现)但我在想办法避免这种情况。我想知道如何(如果可能的话)将这些模式组合成一个。这是我能想到的最快的方法。此外,1)您不能将100个正则表达式组合到一个调用中,因为构建正则表达式非常复杂,匹配失败的机会很少。这是最好的方法之一。2) 在我看来,与这种方法相比,将多个正则表达式组合成一个正则表达式(如果可能的话)使用preg_match执行会慢一些。请记住这里的关键是数组上的回调函数
    ,这是在php中处理数组和类似情况的最快方法。您应该在答案中添加此解释,一个有效的答案可以是“这是不可能的,只是在模式上循环”,但我想知道为什么:)Thx!实际上,“回调”不是“循环”!:D循环速度慢,从算法分析中有一个“n”。但数组元素的回调是内部的,相比之下速度非常快。看起来很有效!你能解释一下这个语法吗?再也没有管道了,我不知道该怎么办。。。谢谢@达米恩:我补充了一个解释。
    (?=                                     # 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