PHP - 智能,容错字符串比较

时间:2010-02-17 23:20:29

标签: php string comparison

我正在寻找常规或寻找容错字符串比较的方法。

假设我们有测试字符串Čakánka - 是的,它包含CE字符。

现在,我想接受以下任何字符串OK

  • cakanka
  • cákanká
  • ČaKaNKA
  • CAKANKA
  • CAAKNKA
  • CKAANKA
  • cakakNa

问题是,我经常在单词中切换字母,并且我希望尽量减少用户的挫败感,因为他们无法(即你匆忙)正确地写一个单词。

所以,我知道如何进行ci比较(只需将其设为小写:]),我可以删除CE字符,我只是无法绕过容忍几个切换字符。

此外,您经常将一个字符放在错误的位置(character => cahracter),但有时会将其移到多个位置(character => {{1只是因为一个手指在写作过程中很懒惰。

谢谢:]

3 个答案:

答案 0 :(得分:4)

不确定(特别是关于口音/特殊字符的内容,您可能需要先处理),但对于位置错误或缺失的字符, {{ 3}}函数,计算两个字符串之间的 levenshtein ,可能会帮助您(引用)

int levenshtein  ( string $str1  , string $str2  )
int levenshtein  ( string $str1  , string $str2  , int $cost_ins  , int $cost_rep  , int $cost_del  )
  

Levenshtein距离定义为   你最少的人物数量   必须替换,插入或删除   将str1转换为str2


其他可能有用的功能可以是Levenshtein distancesoundexsimilar_text

这些功能的手册页上的一些用户注释,尤其是metaphone也可能为您带来一些有用的东西; - )

答案 1 :(得分:3)

您可以将单词音译为拉丁字符,并使用像Soundex这样的语音算法从您的单词中获取精华,并将其与您拥有的单词进行比较。在您的情况下,除了最后一个C252之外,您的所有字词都为C250


修改 levenshteinsimilar_text等比较函数的问题在于您需要为每对输入值和可能的匹配值调用它们。这意味着如果您拥有一个包含100万条目的数据库,则需要将这些功能称为100万次。

但计算某种摘要的soundexmetaphone等函数可以帮助减少实际比较的次数。如果为数据库中的每个已知单词存储soundexmetaphone值,则可以非常快速地减少可能的匹配数。之后,当可能的匹配值集合减少时,您可以使用比较函数来获得最佳匹配。

以下是一个例子:

// building the index that represents your database
$knownWords = array('Čakánka', 'Cakaka');
$index = array();
foreach ($knownWords as $key => $word) {
    $code = soundex(iconv('utf-8', 'us-ascii//TRANSLIT', $word));
    if (!isset($index[$code])) {
        $index[$code] = array();
    }
    $index[$code][] = $key;
}

// test words
$testWords = array('cakanka', 'cákanká', 'ČaKaNKA', 'CAKANKA', 'CAAKNKA', 'CKAANKA', 'cakakNa');
echo '<ul>';
foreach ($testWords as $word) {
    $code = soundex(iconv('utf-8', 'us-ascii//TRANSLIT', $word));
    if (isset($index[$code])) {
        echo '<li> '.$word.' is similar to: ';
        $matches = array();
        foreach ($index[$code] as $key) {
            similar_text(strtolower($word), strtolower($knownWords[$key]), $percentage);
            $matches[$knownWords[$key]] = $percentage;
        }
        arsort($matches);
        echo '<ul>';
        foreach ($matches as $match => $percentage) {
            echo '<li>'.$match.' ('.$percentage.'%)</li>';
        }
        echo '</ul></li>';
    } else {
        echo '<li>no match found for '.$word.'</li>';
    }
}
echo '</ul>';

答案 2 :(得分:1)

拼写检查程序执行fuzzy string comparison之类的操作。也许您可以根据该参考调整算法。或者从像Firefox这样的开源项目中获取拼写检查器猜测代码。