AAA Главная
Примеры PHP Примеры JavaScript Примеры Ajax Примеры CSS,HTML

Проверка похожести двух слов

Точное сравнение двух символьных строк, даже регистронезависимое, выполнить нетрудно. А как быть, если в одной их них встречаются символы другого алфавита, похожие по написанию?

Так, буква "E" в русской и английской раскладке имеет одинаковое написание, или вместо русской "Н(н)" можно написать английскую "H(h)".

Этим могут воспользоваться всякие ...., например оставить сообщение на форуме якобы от администрации, зарегистрировав ник, внешне похожий на ник администратора. Для проверки похожести двух строк можно использовать следующую функцию:

// -----------------------------------------------------
// Функция проверки похожести двух слов
// Параметры: $name1 и $name2 - слова для проверки
// $register = TRUE - проверка регистронезависима
//           = FALSE - проверка с учетом регистра
// На выходе: TRUE - слова похожи, FALSE - отличаются
// -----------------------------------------------------
function chk_similarity($word1, $word2, $register=false) {
  // Очистить слова от служебных символов
  $word1=preg_replace("/[^0-9a-zа-я]/i","",$word1);
  $word2=preg_replace("/[^0-9a-zа-я]/i","",$word2);
 
  // Возврат FALSE если длина слов различается
  // или хотя бы одно из них пустое
  if ((strlen($word1)!==strlen($word2)) || strlen($word1)*strlen($word2)==0) {
    return false;
  }
 
  // Заполнить таблицу соответствий
  $pattern1="";
  $pattern2=Array();
 
  $pattern1.="aа";
  $pattern2[]="[аa]";
  $pattern2[]="[аa]";
 
  $pattern1.="AА";
  $pattern2[]="[АA]";
  $pattern2[]="[АA]";
 
  $pattern1.="BВ";
  $pattern2[]="[BВ]";
  $pattern2[]="[BВ]";
 
  $pattern1.="bь";
  $pattern2[]="[bь]";
  $pattern2[]="[bь]";
 
  $pattern1.="cс";
  $pattern2[]="[cс]";
  $pattern2[]="[cс]";
 
  $pattern1.="CС";
  $pattern2[]="[CС]";
  $pattern2[]="[CС]";
 
  $pattern1.="eе";
  $pattern2[]="[eе]";
  $pattern2[]="[eе]";
 
  $pattern1.="EЕ";
  $pattern2[]="[EЕ]";
  $pattern2[]="[EЕ]";
 
  $pattern1.="HН";
  $pattern2[]="[HН]";
  $pattern2[]="[HН]";
 
  $pattern1.="iI1l";
  $pattern2[]="[iI1l]";
  $pattern2[]="[iI1l]";
  $pattern2[]="[iI1l]";
  $pattern2[]="[iI1l]";
 
  $pattern1.="kк";
  $pattern2[]="[kк]";
  $pattern2[]="[kк]";
 
  $pattern1.="KК";
  $pattern2[]="[KК]";
  $pattern2[]="[KК]";
 
  $pattern1.="MМ";
  $pattern2[]="[MМ]";
  $pattern2[]="[MМ]";
 
  $pattern1.="nп";
  $pattern2[]="[nп]";
  $pattern2[]="[nп]";
 
  $pattern1.="oо0";
  $pattern2[]="[oо0]";
  $pattern2[]="[oо0]";
  $pattern2[]="[oо0]";
 
  $pattern1.="OО0";
  $pattern2[]="[OО0]";
  $pattern2[]="[OО0]";
  $pattern2[]="[OО0]";
 
  $pattern1.="pр";
  $pattern2[]="[pр]";
  $pattern2[]="[pр]";
 
  $pattern1.="PР";
  $pattern2[]="[PР]";
  $pattern2[]="[PР]";
 
  $pattern1.="rг";
  $pattern2[]="[rг]";
  $pattern2[]="[rг]";
 
  $pattern1.="TТ";
  $pattern2[]="[TТ]";
  $pattern2[]="[TТ]";
 
  $pattern1.="uи";
  $pattern2[]="[uи]";
  $pattern2[]="[uи]";
 
  $pattern1.="xх";
  $pattern2[]="[xх]";
  $pattern2[]="[xх]";
 
  $pattern1.="XХ";
  $pattern2[]="[XХ]";
  $pattern2[]="[XХ]";
 
  $pattern1.="yу";
  $pattern2[]="[yу]";
  $pattern2[]="[yу]";
 
  $pattern1.="YУ";
  $pattern2[]="[YУ]";
  $pattern2[]="[YУ]";
 
  $pattern1.="З3";
  $pattern2[]="[З3]";
  $pattern2[]="[З3]";
 
  $pattern1.="ч4";
  $pattern2[]="[ч4]";
  $pattern2[]="[ч4]";
 
  $pattern1.="Ч4";
  $pattern2[]="[Ч4]";
  $pattern2[]="[Ч4]";
 
  // Составить регулярное выражение для проверки
  $tmp="^";
  for ($i=0; $i<strlen($word1); $i++) {
    $letter=$word1[$i];
    $pos=strpos($pattern1,$letter);
    if ($pos===false) {
      $tmp.=$letter;
    }
    else {
      $tmp.=$pattern2[$pos];
    }
  }
  $tmp.="$";
 
  // Возврат TRUE - слова похожи или равны
  // FALSE - слова отличаются
  return($register?preg_match('/'.$tmp.'/i',$word2):preg_match('/'.$tmp.'/',$word2));
}

Примеры использования:

$admin_name="ManHunter";   // Ник администратора
 
$chk_name="МаnНuntеr";     // Буквы "М", "Н" и "е" в русской раскладке
chk_similarity($admin_name, $chk_name);     // --> TRUE
 
$chk_name="manhunter";     // Буквы в нижнем регистре
chk_similarity($admin_name, $chk_name);     // --> FALSE
chk_similarity($admin_name, $chk_name, 1);  // --> TRUE
 
$chk_name="[Man_Hunter]";  // Использованы служебные символы
chk_similarity($admin_name, $chk_name);     // --> TRUE
 
$chk_name="-=mAnHuNtEr=-"; // Регистр и служебные символы
chk_similarity($admin_name, $chk_name);     // --> FALSE
chk_similarity($admin_name, $chk_name, 1);  // --> TRUE
 
$chk_name="ManHanter";     // Слово не похоже
chk_similarity($admin_name, $chk_name);     // --> FALSE
chk_similarity($admin_name, $chk_name, 1);  // --> FALSE

Функцию без особого труда можно модифицировать, чтобы она возвращала регулярное выражение для поиска соответствий по базе.

Автор: ManHunter http://www.manhunter.ru/


. Срочная компьютерная помощь красные ворота 09it.ru.

© Copyright 2008-2016 by KDG