Мне нужно сравнить имена, которые могут быть написаны несколькими способами. Например, такое имя, как Сент-Томас, иногда написано, например, St-Thomas или Sant Thomas. Предпочтительно, я ищу, чтобы создать функцию, которая дает процент «равности» для сравнения, как это делают некоторые форумы (например, это сообщение редактируется на 5% ).
Для этого PHP имеет две (основные) встроенные функции.
levenshtein
который подсчитывает, сколько изменений (удалить / добавить / заменить) необходимо для создания строки2 из строки1. (ниже – лучше)
а также
similar_text
который возвращает количество совпадающих символов (выше – лучше). Обратите внимание, что вы можете передать ссылку в качестве третьего параметра, и она даст вам процент.
<?php $originalPost = "Here's my question to stack overflou. Thanks /h2ooooooo"; $editedPost = "Question to stack overflow."; $matchingCharacters = similar_text($originalPost, $editedPost, $matchingPercentage); var_dump($matchingCharacters); //int(25) var_dump($matchingPercentage); //float(60.975609756098) (hence edited 40%) ?>
Расстояние редактирования между двумя строками символов обычно относится к расстоянию Левенштейна.
Проверьте levenshtein()
, который делает то, что вы хотите, и является сравнительно эффективным (но не очень эффективным): http://www.php.net/manual/en/function.levenshtein.php
Вы можете использовать разные подходы.
Вы можете использовать similar_text()
для проверки сходства.
ИЛИ
Вы можете использовать levenshtein()
чтобы узнать …
Расстояние Левенштейна определяется как минимальное количество символов, которые вы должны заменить, вставить или удалить, чтобы преобразовать str1 в str2
И затем проверьте разумный порог для вашей проверки.
$v1 = 'pupil'; $v2 = 'people'; # TRUE if $v1 & $v2 have similar pronunciation soundex($v1) == soundex($v2); # Same but it use a more accurate comparison algorithm metaphone($v1) == metaphone($v2); # Calculate how many common characters between 2 strings # Percent store the percentage of common chars $common = similar_text($v1, $v2, $percent); # Compute the difference of 2 text $diff = levenshtein($v1, $v2);
Таким образом, либо levenshtein($v1, $v2)
либо similar_text($v1, $v2, $percent)
будут делать это за вас, но все же есть компромисс . Сложность алгоритма levenshtein()
равна O(m*n)
, где n и m – длина v1 и v2 (довольно хорошо по сравнению с similar_text()
, что равно O(max(n,m)**3)
, но все же дорогой).