Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php中的近似字符串匹配_Php_Preg Match All_String Comparison - Fatal编程技术网

php中的近似字符串匹配

php中的近似字符串匹配,php,preg-match-all,string-comparison,Php,Preg Match All,String Comparison,假设我需要比较两个变量 $team="Benfica(U23):Vitoria Guimaraes(U23)"; 及 对于我的purpouse,$team和$team2应该匹配,实际上它们是相同的固定装置,只是用(U23)更改U23 然而,preg_match不像人类那么聪明,所以如果我使用 if (preg_match("/$team/",$team2)) { echo "they match"; } 当然,它们并不匹配。我如何进行近似的预匹配 那么$team和$team2在preg_比赛

假设我需要比较两个变量

$team="Benfica(U23):Vitoria Guimaraes(U23)";

对于我的purpouse,$team和$team2应该匹配,实际上它们是相同的固定装置,只是用(U23)更改U23

然而,preg_match不像人类那么聪明,所以如果我使用

if (preg_match("/$team/",$team2)) {
echo "they match";
}
当然,它们并不匹配。我如何进行近似的预匹配 那么$team和$team2在preg_比赛检查中应该被认为是相同的(非常相似的)? 例如,在上面的preg_匹配中,由于$team中的括号()有4个字符错误,我可以允许这些错误通过preg_匹配吗

可能还有其他情况,比如$team2可能是

$team2="U23 Benfica:Vitoria Guimaraes";
$team2="Benfica (U23):Vitoria Guimaraes U23";
$team2="Benfica U23:Vitoria Guimaraes(U23)";
等等……各种情况下,这只是一个例子。所有这些都应该与$team匹配,如何在php中执行这个近似的字符串匹配


谢谢你编辑:我在看到关于使用类似文本的评论后删除了这个答案,但是我在测试字符串上的实验只得到了第1组和第2组之间的78%。这可能足够好了,但我认为另一种方法可能有用

值得注意的是,除非你开始使用各种伪人工智能的东西,否则你永远不会得到像人类识别这样的东西。从表面上看,你肯定每个单词至少拼写相同。我建议将字符串按任何非字母数字字符拆分成一个数组,然后对数组进行排序,并检查它是否与每个团队的“master”匹配

它看起来像(这是未经测试的,$模式可能需要更多的工作)


您可以使用
levenshtein($team,$team2)
获得一个表示字符串差异程度的数字,然后定义一个阈值来决定要容忍的程度

if (levenshtein($team, $team2) < 3) {
    echo "string are similar";
} else {
    echo "string are not similar";
}
if(levenshtein($team,$team2)<3){
回声“字符串相似”;
}否则{
echo“字符串不相似”;
}

另一种方法是在多重分解数组上使用数组相交

移除
()
并用空格替换。
在空格和冒号上分解并过滤掉所有空的

使用array_intersect查看有多少相等的项,并查看是否与唯一项的计数匹配

当然,如果您需要,可以通过计数是否在裕度范围内进行校准

$team1="U23 Benfica:Vitoria Guimaraes";
$team2="Benfica (U23):Vitoria Guimaraes U23";
var_dump(match($team1, $team2));

$team1="U23 Benfica:Vitoria Guimaraes";
$team2="Benfica U23:Vitoria Guimaraes(U23)";
var_dump(match($team1, $team2));

$team1="Benfica U23:Vitoria Guimaraes(U23)";
$team2="Benfica (U23):Vitoria Guimaraes U23";
var_dump(match($team1, $team2));

function match($s1, $s2){
    // remove the ( and ) and replace with space
    $s1 = str_replace(["(",")"], " ", $s1); 
    $s2 = str_replace(["(",")"], " ", $s2);

    $delimiters = [" ", ":"]; // add more delimiters if needed
    // explode on $delimiters and remove empty values
    $arr1 = array_filter(multiexplode($delimiters,$s1)); 
    $arr2 = array_filter(multiexplode($delimiters,$s2));
//var_dump($arr1, $arr2);

    // How many items is equal between $arr1 and $arr2
    $intersect = count(array_unique(array_intersect($arr1, $arr2)));

    // is the count of equal items the same as the count of items in the strings
    if($intersect == count(array_unique($arr1)) && $intersect == count(array_unique($arr2))){
        return true;
    }else{
        return false;
    }

}

// From PHP manual explode
function multiexplode ($delimiters,$string) {

    $ready = str_replace($delimiters, $delimiters[0], $string);
    $launch = explode($delimiters[0], $ready);
    return  $launch;
}
返回:

bool(true)
bool(true)
bool(true)

也许您应该从字符串中删除
()
,然后比较它们?这可能就是您想要的:。Regex不是这个工作的合适工具。mulder,这不是一个解决方案,我可以完全用countrary$team2=“本菲卡(U23):圭马拉斯维多利亚(U23)”;和$team=“本菲卡U23:Vitoria Guimareas U23”;如果您正在寻找本机PHP函数,那么这是不可能的。有可能用一个算法创建一个函数来完成你想要的任务,你可以尝试创建它,你可以签出这个函数。在这种情况下,这不起作用,因为字符串不一样。单词的顺序不一样,因此会得到很高的分数。请看这里:
$team1="U23 Benfica:Vitoria Guimaraes";
$team2="Benfica (U23):Vitoria Guimaraes U23";
var_dump(match($team1, $team2));

$team1="U23 Benfica:Vitoria Guimaraes";
$team2="Benfica U23:Vitoria Guimaraes(U23)";
var_dump(match($team1, $team2));

$team1="Benfica U23:Vitoria Guimaraes(U23)";
$team2="Benfica (U23):Vitoria Guimaraes U23";
var_dump(match($team1, $team2));

function match($s1, $s2){
    // remove the ( and ) and replace with space
    $s1 = str_replace(["(",")"], " ", $s1); 
    $s2 = str_replace(["(",")"], " ", $s2);

    $delimiters = [" ", ":"]; // add more delimiters if needed
    // explode on $delimiters and remove empty values
    $arr1 = array_filter(multiexplode($delimiters,$s1)); 
    $arr2 = array_filter(multiexplode($delimiters,$s2));
//var_dump($arr1, $arr2);

    // How many items is equal between $arr1 and $arr2
    $intersect = count(array_unique(array_intersect($arr1, $arr2)));

    // is the count of equal items the same as the count of items in the strings
    if($intersect == count(array_unique($arr1)) && $intersect == count(array_unique($arr2))){
        return true;
    }else{
        return false;
    }

}

// From PHP manual explode
function multiexplode ($delimiters,$string) {

    $ready = str_replace($delimiters, $delimiters[0], $string);
    $launch = explode($delimiters[0], $ready);
    return  $launch;
}
bool(true)
bool(true)
bool(true)