Только для читателей Lifeexample возможно открыть интернет-магазин на Moguta.CMS со скидкой в 15%
PHP Автоматическое исправление неправильной раскладки строки
Здравствуйте, уважаемые читатели блога LifeExample, Давно хотел написать статью о том, как средствами серверного языка PHP реализовать автоматическое исправление неправильной раскладки строки. Все мы пользуемся поисковиками Google и Яндекс, и каждый из вас уже давно привык не думать о том в какой раскладке ввести свой запрос, ведь умный поисковик сам вычислит, что вводимый текст печатается не в той раскладке и выдаст правильный саджест.
Саджест (suggest) – выпадающий список с частыми поисковыми запросами, схожими с введенным словом.

Приведенная иллюстрация демонстрирует, как ведет себя Яндекс при вводе запроса "Cvtyf rjlbhjdrb" (Смена раскладки). Как видите, в выпадающем списке подсказки выдаются в понятной раскладке.
Suggest на PHP как у Яндекса
Суть задачи заключается в том, чтобы по началу вводимого слова привести его к верной раскладке и выбрать из БД подходящие запросы.
На первый взгляд может показаться, что задача довольно простая, и достаточно прописать соответствие правильных и не правильных символов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php function correctString ($string) { $search = array( "й","ц","у","к","е","н","г","ш","щ","з","х","ъ", "ф","ы","в","а","п","р","о","л","д","ж","э", "я","ч","с","м","и","т","ь","б","ю" ); $replace = array( "q","w","e","r","t","y","u","i","o","p","[","]", "a","s","d","f","g","h","j","k","l",";","'", "z","x","c","v","b","n","m",",","." ); return preg_replace($search, $replace, $string); } ?> |
Действительно, применив данную функцию correctString() к переданной строке, мы получим слово в нужной раскладке, но изюминкой задачи является именно выявление необходимости применения такой функции к вводимому тексту?
Как определить, что раскладка неправильная
Чтобы программа понимала, что раскладка не верная, нужно определить набор не существующих лемм русского языка.
…
и в во не он на я что с со тот быть а весь это как она по но они к у ты из мы за вы так же от сказать этот который мочь человек о один ещё бы такой только себя своё какой когда уже для вот кто да
…
Следуя данным частотного словаря С.А. Шарова , всего таких лемм, или еще их можно назвать словоформами, существует 69307 шт.
Конвертировав словоформы в неправильную раскладку, получим примерно такой массив:
1 | $Words = array('b', 'd', 'yt', 'jy', 'yf', 'z', 'xnj', 'c', 'cj', 'njn', ',snm', 'f', 'dtcm', "'nj", 'rfr', 'jyf', 'gj', 'yj', 'jyb', 'r', 'e', 'ns', 'bp', 'pf', 'ds', 'nfr', ';t', 'jn', 'crfpfnm',"'njn", 'rjnjhsq', 'vjxm', 'xtkjdtr', 'j', 'jlby', 'tot', ',s', 'nfrjq', 'njkmrj', 'ct,z', 'cdjt', 'rfrjq', 'rjulf', 'e;t', 'lkz', 'djn', 'rnj', 'lf', 'ujdjhbnm', 'ujl', 'pyfnm', 'vjq', 'lj', 'bkb', 'tckb', 'dhtvz', 'herf', 'ytn', 'cfvsq', 'yb', 'cnfnm', ',jkmijq', 'lf;t', 'lheujq', 'yfi', 'cdjq', 'ye', 'gjl', 'ult', 'ltkj', 'tcnm', 'cfv', 'hfp', 'xnj,s', 'ldf', 'nfv', 'xtv', 'ukfp', ';bpym', 'gthdsq', 'ltym', 'nenf', 'ybxnj', 'gjnjv', 'jxtym', '[jntnm', 'kb', 'ghb', 'ujkjdf', 'yflj', ',tp', 'dbltnm', 'blnb', 'ntgthm', 'nj;t', 'cnjznm', 'lheu', 'ljv', 'ctqxfc', 'vj;yj', 'gjckt', 'ckjdj', 'pltcm', 'levfnm', 'vtcnj', 'cghjcbnm', 'xthtp', 'kbwj', 'njulf', 'dtlm', '[jhjibq', 'rf;lsq', 'yjdsq', ';bnm', 'ljk;ys', 'cvjnhtnm', 'gjxtve', 'gjnjve', 'cnjhjyf', 'ghjcnj', 'yjuf', 'cbltnm', 'gjyznm', 'bvtnm', 'rjytxysq', 'ltkfnm', 'dlheu', 'yfl', 'dpznm', 'ybrnj', 'cltkfnm', 'ldthm', 'gthtl', 'ye;ysq', 'gjybvfnm', 'rfpfnmcz', 'hf,jnf', 'nhb', 'dfi', 'e;', 'ptvkz', 'rjytw', 'ytcrjkmrj', 'xfc', 'ujkjc', 'ujhjl', 'gjcktlybq', 'gjrf', '[jhjij', 'ghbdtn', 'pljhjdj', 'pljhjdf', 'ntcn', 'yjdjq', 'jr', 'tuj', 'rjt', 'kb,j', 'xnjkb', 'ndj.', 'ndjz', 'nen', 'zcyj', 'gjyznyj', 'x`', 'xt'); |
Далее можно сделать вывод: если слово имеет в своем составе последовательность символов из этого набора, то оно является русским. Конечно, нельзя быть уверенным на 100% в абсолютности данного утверждения, но часть задачи уже решена.
На том же сайте словаря С.А. Шарова, приведен архив с леммами, отсортированными по частоте использования их в русском языке. Используя, которые можно усовершенствовать алгоримт и увеличить его точность.
Для не сложных преобразований, например в переписке пользователей чата, этого может быть достаточно, и можно написать функцию автоматической смены раскладки основываясь на данном подходе.
Тем не менее в крупных проектах, этим методом уже не обойтись. Чтобы реализовать что-то похожее на саджест яндекса я рекомендую использовать библиотеку Text_LangCorrect, написанную на PHP.
Text_LangCorrect – имеет мощный алгоритм вычисления раскладки и ее правильности, и на момент написания статья является чуть ли не единственной доступной библиоткой, позволяющей автоматически изменять раскладку слова.
Сама же библиотека тщательно снабжена комментариями к каждой из ее методов, поэту можно очень быстро разобраться в ее устройстве. При ее использовании можно с лёгкостью конвертировать текст такого формата "смtyf ytправиkmyjq hfcrладки" в читаемый вид "смена неправильной раскладки".
Пример использования:
1 2 3 4 5 6 | require_once ('ReflectionTypeHint.php'); require_once ('Text/LangCorrect.php'); require_once ('UTF8.php'); $corrector = new Text_LangCorrect(); echo iconv('utf-8', 'windows-1251', $corrector->parse('смtyf ytправиkmyjq hfcrладки цццюдшауучфьзду.ru')); |
Как видите, происходит подключение необходимых файлов для работы библиотеки, создается экземпляр Text_LangCorrect и методом parse() делает все необходимые преобразования.
Выпадающий список подсказок
Выпадающий список подсказок, он же саджест, может работать по следующему алгоритму.
- Ввод текста в строку.
- Проверка количества введенных символов.
- Если символов больше трех, отправлять AJAX запрос с введенным текстом на проверку корректировки.
- На сервер обработать введенный текст библиотекой LangCorrect, вычислив верную раскладку.
- Взять из базы данных подходящие подсказки в верной раскладке и отправить их в ответ на AJAX.
- НА строне клиента JavaScript ‘ом вывести выпадающий список.
На этом хочу завершить описание решения для задачи Автоматического исправление неправильной раскладки строки. У кого есть вопросы, пишите в комментариях, подписывайтесь на RSS рассылку.
Читайте также похожие статьи:
Чтобы не пропустить публикацию следующей статьи подписывайтесь на рассылку по E-mail или RSS ленту блога.
Комментарии
Что то не работает
Ошибка какая-то, или просто не переводится строка?
Строка не переводится — Выводится в исходном варианте
Можно попробовать поэкспериментировать с режимами:
2
echo iconv('utf-8', 'windows-1251', $corrector->parse('Ntcnbhjdfybt', $corrector::KEYBOARD_LAYOUT));
или так
2
echo iconv('utf-8', 'windows-1251', $corrector->parse('Ntcnbhjdfybt', $corrector::SIMILAR_CHARS));
Режим SIMILAR_CHARS. Исправление ошибочно набранных букв в словах, которые выглядят одинаково в разных раскладках клавиатуры. Незаметные латинские буквы среди русских исправляются в русские и наоборот. Алгоритм работает достаточно надёжно и быстро.
Режим KEYBOARD_LAYOUT. Исправление ошибочно набранных слов в другой раскладке клавиатуры. Для определения языка используются N-граммы. Алгоритм может иногда ошибаться, работает в разы медленнее, чем SIMILAR_CHARS. Алгоритм постоянно совершенствуется. Для поддержания качества существует тестовый набор слов, который в поставку не входит.
У меня совсем не работает, пробовал на локальном сервере denwer
Parse error: syntax error, unexpected T_FUNCTION in S:\home\test1.ru\ajax\text\UTF8.php on line 2868
Дмитрий PHP 5.3 ?
Всем привет
Частично работает в режиме KEYBOARD_LAYOUT.
Строка: «Xnj ltkfnm yt hf,jnftn?»
Результат: «Xnj делать yt работает?»
Не знаю как люди тестируют…
По алгоритму KEYBOARD_LAYOUT не определяет, если слово короче 2х символов. Если слитно Xnjyt , то успешно