PHP - akıllı, hata hoşgörüyle string karşılaştırma

3 Cevap php

Ben de rutin veya hata hoşgörüyle dize karşılaştırma aramak için yol arıyorum.

Diyelim ki, biz sınama dizesi var Čakánka - evet, CE karakterler içeriyor.

Şimdi, OK olarak aşağıdaki dizelerden birini kabul etmek istiyorum:

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

Sorun sık sık kelime harfleri geçiş, ve ben doğru bir kelime yazmak için (yani acele konum) mümkün olmayan kullanıcının hayal kırıklığı en aza indirmek istiyorsanız olmasıdır.

Ben CE karakterleri silebilirsiniz, ben sadece birkaç tolere etrafında başımı sarmak olamaz karakterleri açık: Yani, (] sadece küçük harf yapmak) ci karşılaştırma yapmak için biliyorum.

Ayrıca, sık sık (character => cahracter), ama bazen birden çok yerde bunu vardiya (character => {[yanlış yerde değil sadece bir karakter koymak (3)]}), bir parmak yazma sırasında tembel oldu çünkü.

Teşekkür ederim:]

3 Cevap

(especially about the accents / special characters stuff, which you might have to deal with first), ama yanlış yerde veya eksik karakterler için emin değilim, levenshtein function, bu hesaplar Levenshtein distance {[( 4)]}:

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

The Levenshtein distance is defined as the minimal number of characters you have to replace, insert or delete to transform str1 into str2


Other possibly useful functions could be soundex, similar_text, or metaphone.

Ve bu fonksiyonların elle sayfalarında kullanıcı notları bazı özellikle manual page of levenshtein size bazı yararlı şeyler de getirebilir ;-)

Sen latin karakter kelimeleri transliterate ve kelime özünü almak ve sahip olanlar karşılaştırmak için Soundex gibi bir fonetik algoritma kullanabilir. Senin durumunda o C250 olan sonuncusu hariç sözlerin tümü için C252 olacaktır.


levenshtein veya similar_text gibi karşılaştırmalı fonksiyonları ile Edit sorun giriş değeri ve olası eşleşen değerin her bir çifti için onları aramak gerekir olmasıdır. Yani, 1 milyon girişleri ile bir veritabanı varsa bu fonksiyonları 1000000 kez aramak gerekir anlamına gelir.

Ama sindiriminin çeşit hesaplamak soundex veya metaphone gibi fonksiyonlar, gerçek karşılaştırmalar sayısını azaltmaya yardımcı olabilir. Eğer soundex ya da veritabanında bilinen her kelime için metaphone değerini saklamak varsa, çok hızlı bir şekilde olası eşleşmelerin sayısını azaltabilir. Olası eşleşen değer kümesi azalır Daha sonra, o zaman iyi maç olsun karşılaştırmalı işlevlerini kullanabilirsiniz.

İşte bir örnek:

// 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>';

Yazım dama fuzzy string comparison . Perhaps you can adapt an algorithm based on that reference. Or grab the spell checker guessing code from an open source project like Firefox gibi bir şey yapmak.