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
??是的。这实际上是一个错误,我改变了。但我需要匹配数组中的所有关键字,包括屈肌
,支持带
&屈肌支持带