PHP – умный, сопоставимый с ошибкой сравнение строк

Я ищу либо рутину, либо способ поиска ошибок, сравнивающих сравнение строк.

Скажем, у нас есть тестовая строка Čakánka – да, она содержит символы СЕ.

Теперь я хочу принять любую из следующих строк как OK :

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

Проблема в том, что я часто переключаю буквы в слово, и я хочу свести к минимуму разочарование пользователя, не будучи в состоянии (то есть вы в спешке), чтобы написать одно слово справа.

Итак, я знаю, как сделать сравнение ci (просто сделайте его строчным:]), я могу удалить символы CE, я просто не могу обернуть голову, перенося несколько переключенных символов.

Кроме того, вы часто ставите одного персонажа не только в неправильном месте ( character => cahracter ), но иногда cahracter его несколькими местами ( character => carahcter ), просто потому, что один палец ленив во время записи.

Спасибо :]

Не уверен (особенно об акцентах / спецсимволах, с которыми вам, возможно, придется иметь дело в первую очередь) , но для символов, которые находятся не в том месте или отсутствуют, функция levenshtein , которая вычисляет расстояние Левенштейна между двумя строками, может помочь вам ( цитирование) :

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

Расстояние Левенштейна определяется как минимальное количество символов, которые вы должны заменить, вставить или удалить, чтобы преобразовать str1 в str2

Другие, возможно, полезные функции могут быть soundex , similar_text или metaphone .

И некоторые из примечаний пользователя на страницах руководства этих функций, особенно на странице руководства levenshtein могут принести вам и некоторые полезные вещи 😉

Вы можете транслитерировать слова латинскими символами и использовать фонетический алгоритм, такой как Soundex, чтобы получить сущность от вашего слова и сравнить его с теми, которые у вас есть. В вашем случае это будет C252 для всех ваших слов, кроме последнего, который является C250 .


Редактировать Проблема с сравнительными функциями, такими как levenshtein или similar_text заключается в том, что вам нужно вызывать их для каждой пары входных значений и возможного соответствия. Это означает, что если у вас есть база данных с 1 миллионом записей, вам нужно будет вызвать эти функции 1 миллион раз.

Но функции, такие как soundex или metaphone , которые вычисляют некоторый дайджест, могут помочь уменьшить количество фактических сравнений. Если вы храните значение soundex или metaphone для каждого известного слова в своей базе данных, вы можете очень быстро сократить количество возможных совпадений. Позже, когда набор возможных значений соответствия уменьшается, вы можете использовать сравнительные функции для получения наилучшего соответствия.

Вот пример:

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

Проверка орфографии делает что-то вроде нечеткого сравнения строк . Возможно, вы можете адаптировать алгоритм на основе этой ссылки. Или захватите код проверки проверки орфографии от проекта с открытым исходным кодом, такого как Firefox .