这可能是一个复杂的问题,具体取决于您是在寻找相似的短语还是逐字匹配的短语。
找到准确的逐字匹配非常简单,您只需在标点符号(例如.,;:
)等常见断点上拆分,也可能在连词上拆分(例如and or
)。然而,问题来了,例如,形容词两个短语可能完全相同但有一个单词不同,如下所示:
The world is spinnnig around its axis at a tremendous speed.
The world is spinning around its axis at a magnificent speed.
这将不匹配,因为tremendous
和magnificent
被用来代替另一个。您可能可以解决这个问题,但是,这将是一个更复杂的问题。
回答
如果我们坚持简单的一面,我们只需几行代码就可以实现短语匹配(本例中为4;不包括注释/可读性的格式)。
$wordSplits = 'and or on of as'; //List of words to split on
preg_match_all('/(?<m1>.*?)([.,;:\-]| '.str_replace(' ', ' | ', trim($wordSplits)).' )/i', $para1, $matches1);
preg_match_all('/(?<m2>.*?)([.,;:\-]| '.str_replace(' ', ' | ', trim($wordSplits)).' )/i', $para2, $matches2);
$commonPhrases = array_filter( //Removes blank $key=>$value pairs
array_intersect( //Finds matching paterns
array_map(function($item){
return(strtolower(trim($item))); //Cleans array for $para1 values - removes leading and following spaces
}, $matches1['m1']),
array_map(function($item){
return(strtolower(trim($item))); //Cleans array for $para2 values - removes leading and following spaces
}, $matches2['m2'])
)
);
var_dump($commonPhrases);
/**
OUTPUT:
array(2) {
[0]=>
string(31) "bee pollen is made by honeybees"
[5]=>
string(41) "nature's most completely nourishing foods"
}
/*
上面的代码将发现匹配在标点符号(在模式中定义)上拆分,[...]
它preg_match_all
还将连接单词列表(仅匹配单词列表中带有前后空格的单词)。
词汇表
您可以更改单词列表以包含您喜欢的任何中断,编辑列表直到您获得所需的短语,例如:
$wordSplits = 'and or';
$wordSplits = 'and but if or';
$wordSplits = 'a an as and by but because if in is it of off on or';
标点
您可以将任何您喜欢的标点符号添加到列表中(介于[
and之间]
),但请记住,某些字符确实具有特殊含义,可能需要转义(或适当放置):-
并且^
应该成为\-
and\^
或放置在其特殊含义没有的地方t 发挥作用。
您可以考虑更改:
([.,;:\-]|
至:
([.,;:\-] | //Adding a space before the pipe
这样你就只拆分标点符号,后面跟一个空格。例如:这意味着类似的项目50,000
不会被拆分。
空格和休息
您也可以考虑将空格更改为\s
包含tabs
等newlines
,而不仅仅是空格。像这样:
'/(?<m1>.*?)([.,;:\-]|\s'.str_replace(' ', '\s|\s', trim($wordSplits)).'\s)/i'
这也适用于:
([.,;:\-]\s|
如果你决定走那条路。