Php 预匹配所有具有多个发生的事件

Php 预匹配所有具有多个发生的事件,php,regex,Php,Regex,我有一组字符串和一组数组字。我需要一个函数,返回字符串数组中匹配的单词 下面是字符串和数组的示例 $string=“命名足部屈肌支持带的底层结构。”; $matchList=数组(“多动”、“屈肌”、“调节”、“支持带”、“名称”、“屈肌支持带”); 我尝试了preg\u match\u all。但是,结果并不是所有的单词都匹配 屈肌支持带 这是我使用的方法 $matchList=array\u映射(函数($value){ 返回预报价($value,“/”); },$matchList); $

我有一组字符串和一组数组字。我需要一个函数,返回字符串数组中匹配的单词

下面是字符串和数组的示例

$string=“命名足部屈肌支持带的底层结构。”;
$matchList=数组(“多动”、“屈肌”、“调节”、“支持带”、“名称”、“屈肌支持带”);
我尝试了
preg\u match\u all
。但是,结果并不是所有的单词都匹配

屈肌支持带

这是我使用的方法

$matchList=array\u映射(函数($value){
返回预报价($value,“/”);
},$matchList);
$matchList=内爆(“|”,$matchList);
//设置正则表达式。
$regex='/\b(?:)('.$matchList')(\b)/i';
preg_match_all($regex,$string,$result);

屈肌支持带
不匹配,因为
屈肌
支持带
在正则表达式中具有更高的优先级

忽略
(?:)
的问题您的正则表达式是:

/\b(?:)(Hyperactivity|flexor|Adjustment|retinaculum|name|flexor retinaculum)(\b)/i

flexor-retinaculum
作为单个术语从未被找到,因为
flexor
retinaculum
首先被找到,并且正则表达式一旦匹配就不会递归到开始处

如果希望递归地执行此操作,则需要循环每个
$matchList
项,并对
$string
执行一个新的正则表达式


如果将正则表达式更改为:

/\b(?:)(Hyperactivity|flexor retinaculum|flexor|Adjustment|retinaculum|name)(\b)/i

然后屈肌支持带将作为一个整体匹配,而不是单独匹配。

较短的匹配首先出现,因此按长度排序,以便首先捕获较长的匹配可能会起作用。这将匹配屈肌支持带,但如果匹配,则不会单独匹配屈肌支持带和屈肌支持带。如果屈肌支持带
不匹配,它将匹配屈肌
和支持带:

usort($matchList, function($a, $b){
    return (strlen($b) - strlen($a));
});

$matchList = implode('|', $matchList);
然后使用更简单的正则表达式:

$regex = '/\b(' . $matchList . ')\b/i';
当然,您的字符串是
$string
,因此请使用:

preg_match_all($regex, $string, $result);

得到了解决方案

我用
递归创建了一个自定义函数,它从数组中删除匹配的关键字

function findMatchList( $textString, $wordList )
    {
        $wordList = array_chunk($wordList,500);
        $matchListFinal = [];
        foreach($wordList as $wordSub)
        {
            $wordListString = implode( '|', $wordSub );

            // Set the regex.
            $regex = '/\b(?:)(' . $wordListString . ')(\b)/i';

            preg_match_all( $regex, $textString, $matchList );
            if( isset( $matchList[0] ) && count( $matchList[0] ) ) {

                $wordSub = array_udiff( $wordSub, $matchList[0], 'strcasecmp' );

                $matchList = array_merge( $matchList[0], $this->_findMatchList( $textString, $wordSub ) );
            }
            else
                $matchList = [];

            $matchListFinal = array_merge($matchListFinal,$matchList);

        }

        return $matchListFinal;
    }
这里我使用
array\u chunk
来处理
wordList
数组的长度是否超过
500
长度。在我的场景中,数组中有500多个单词

function findMatchList( $textString, $wordList )
    {
        $wordList = array_chunk($wordList,500);
        $matchListFinal = [];
        foreach($wordList as $wordSub)
        {
            $wordListString = implode( '|', $wordSub );

            // Set the regex.
            $regex = '/\b(?:)(' . $wordListString . ')(\b)/i';

            preg_match_all( $regex, $textString, $matchList );
            if( isset( $matchList[0] ) && count( $matchList[0] ) ) {

                $wordSub = array_udiff( $wordSub, $matchList[0], 'strcasecmp' );

                $matchList = array_merge( $matchList[0], $this->_findMatchList( $textString, $wordSub ) );
            }
            else
                $matchList = [];

            $matchListFinal = array_merge($matchListFinal,$matchList);

        }

        return $matchListFinal;
    }

(?:)
应该做什么?什么是
带标签($text\u数组)
?什么不起作用?如果您想使用
$string
,我认为代码应该是这样的
$regex='/\b(?:'.$matchList.')\b/I'
可能
$text\u数组
应该是
$string
??是的。这实际上是一个错误,我改变了。但我需要匹配数组中的所有关键字,包括
屈肌
支持带
&
屈肌支持带