Регистрация Войти
Войти через VK Войти через FB Войти через Google Войти через Яндекс
Войти через VK Войти через FB Войти через Google Войти через Яндекс
Поиск по сайту
Проверка похожести двух слов
Точное сравнение двух символьных строк, даже регистронезависимое, выполнить нетрудно. А как быть, если в одной их них встречаются символы другого алфавита, похожие по написанию?
Так, буква "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/
.
Прокомментировать/Отблагодарить