【问题标题】:PHP string matchingPHP 字符串匹配
【发布时间】:2015-01-31 00:42:02
【问题描述】:

我一直在编写一个匹配 2 字符的 PHP 函数。这是示例。这是我的阵列 1

$arr1 = array(
    "ABC" => 'c4',
    "A" => 'c1',
    "AC" => 'c2',
    "ACC" => 'c3',
    "aBC" => 'c5',
);

这是数组 2

$arr2 = array('ACXMASD','aCXMASD','ACCXMASD','ABCDXMASD','ABXAAAAS');

现在我需要找到的是数组 1 的键和数组 2 的值中的紧密匹配

考虑 ACXMASD:

现在将它与我的数组 1 进行比较。我应该将 AC 作为最接近的匹配,而不是 A 或 ACC

同样考虑 ABXAAAAS。我应该将“A”作为最佳匹配,而不是 ABC。

换句话说,我希望键与字符串完全匹配。

我已经尝试过从 stackoverflow 中找到的这段代码。但它的问题是如下。

我的功能

function findClosestMatchingString($s) {

    $stringEditDistanceThreshold = 7;
    $arr2 = array(
                  "ABC" => 'c4',
                  "A" => 'c1',
                  "AC" => 'c2',
                  "ACC" => 'c3',
                  "aBC" => 'c5',
                  );
    $closestDistanceThusFar = $stringEditDistanceThreshold + 1;
    $closestMatchValue      = null;

    foreach ($arr2 as $key => $value) {
        $editDistance = levenshtein($key, $s);
        echo "$editDistance <br/>";
        // exact match
        if ($editDistance == 0) {
            return $value;

            // best match thus far, update values to compare against/return
        } elseif ($editDistance < $closestDistanceThusFar) {
            $closestDistanceThusFar = $editDistance;
            $closestMatchValue[]     = $value;
        }
    }

    return $closestMatchValue; // possible to return null if threshold hasn't been met
}

$arr1 = array('ACXMASD','aCXMASD','ACCXMASD','ABCDXMASD','ABXAAAAS');
// do the mapping
print_r(findClosestMatchingString('ABXAAAAS'));

现在的问题是 print_r 返回 c4。但我希望它返回 c1 因为该键完全匹配。值为 c4 的键是 ABC,但我的字符串有 ABX。

谢谢

【问题讨论】:

  • 我想你不明白 Levenshtein 距离是什么。
  • 要将A 更改为ABXAAAAS 需要添加BXAAAAS,即距离为7。要将ABC 更改为ABXAAAAS 需要将C 替换为X 并添加@ 987654331@,距离只有6。
  • 我明白了。让我试着玩一下。你认为我的方向是对的。我的意思是我真的需要使用 Levenshtein 距离,或者这可以通过 PHP 中的其他一些方式来完成(如果你理解我所追求的)。再次感谢
  • 我认为您不应该使用 Levenshtein。我认为您应该只使用 strpos() 并选择匹配的最长密钥。
  • 听起来您正试图从相关设置值的开头找到与其中一个键匹配的最长子字符串。这是正确的吗?

标签: php regex fuzzy-logic


【解决方案1】:

这可能就是你要找的东西:

<?php 
$arr1 = array('ACXMASD','aCXMASD','ACCXMASD','ABCDXMASD','ABXAAAAS');

$arr2 = array(
        "ABC" => 'c4',
        "A" => 'c1',
        "AC" => 'c2',
        "ACC" => 'c3',
        "aBC" => 'c5',
);

krsort($arr2);

foreach($arr1 as $val1)
{
    echo "<br /> Searching for $val1";
    foreach($arr2 as $var => $val2)
    {
        if(strpos($val1, $var) !== false)
        {
            echo "<br />Best Case for " . $val1 . " is " . $val2 . " " . $var . " <br />";
            break;
        }
    }

}
?>

【讨论】:

  • 几乎不是“最好的情况”
  • 我只是按照 Barmar 所说的去做。我使用了 strpos ,然后我找到了最长的字符串。 $a = "ACCXMASD"; $arr2 = array( "ACC" => 'c3', "ABC" => 'c4', "AC" => 'c2', "aBC" => 'c5', "A" => 'c1', ); foreach($arr2 as $key => $v){ if(strpos($a, $key) === 0){ $m[] = $key; } } print_r($m);
猜你喜欢
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-07
  • 1970-01-01
相关资源
最近更新 更多