«Автопереключение раскладки» в php-приложениях

Доброго времени суток!

С недавнего времени я занимаюсь разработкой системы чатов, так сказать чаты 3.0. Данная идея пришла после того как познакомился с такой интересной и удобной штукой как comet-сервер Realplexor от dkLab. Но сейчас не об этом…

Основной движок написал, чат работает, пользователи общаются, все вроде бы ничего, но есть одно НО! Все же мы люди и бывает забываем переключить раскладку клавиатуры с английской на русскую, такое бывает. После написания n-го количества слов отправляем сообщение и что видим — написали не в той раскладке, и редко кому захочется заново переписывать этот текст, а читателям не всем захочется переводить Ваши каракули. И решено было придумать какой-нибудь очень простой способ исправления таких сообщений.


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

Полдела сделано осталось составить алгоритм работы и написать функцию.

Алгоритм очень простой:
  1. Переводим строку в нижний регистр
  2. Удаляем ненужные символы
  3. Разбиваем ее на слова
  4. Ищем совпадения слов, которые нашли в википедии, и запоминаем их количество
  5. Если количество совпадений больше или равно указанному нами пределу при котором считать что предложение написано не в правильной раскладке — поменять буквы и символы в предложении на правильные.


Просто! Не так ли?

Функция на php выглядит примерно так:

function orfFilter($string){
	/*Кол-во попадений не правильных слов в строке чтобы считать что строка написана в не правильной раскладке*/
	$countErrorWords = 1;
	/*счетчик не правильных слов*/
	$countError = 0;
	/*При попадении таких слов, считать что выбрана не правильная раскладка клавиатуры*/
	$errorWords = 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');
	/*Символы которые нужно исключить из строки*/
	$delChar = array('!' => '', '&' => '', '?' => '', '/' => '');
	/*Исключения*/
	$expectWord = array('.ьу'=>'/me');
	/*Символы для замены на русские*/
	$arrReplace = 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'=>'ь', ','=>'б', '.'=>'ю', '/'=>'.', '`'=>'ё', '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'=>'Ь', '<'=>'Б', '>'=>'Ю', '?'=>',', '~'=>'Ё', '@'=>'"', '#'=>'№', '$'=>';', '^'=>':', '&'=>'?');
	/*Меняем ключ со значением в массиве $arrReplace*/
	$arrReplace2 = array_flip($arrReplace);
	/*Удаляем некоторые символы*/
	unset($arrReplace2['.']);
	unset($arrReplace2[',']);
	unset($arrReplace2[';']);
	unset($arrReplace2['"']);
	unset($arrReplace2['?']);
	unset($arrReplace2['/']);
	/*И соединяем массивы в один*/
	$arrReplace = array_merge($arrReplace, $arrReplace2);
	/*Переводим в нижний регистр, удаляем пробелы с начала и конца, разбиваем предложение на слова*/
	$string2 = strtr(trim(strtolower($string)), $delChar);
	$arrString = explode(" ", $string2);
	/*Проверям есть ли неправильно написаные слова и считаем их кол-во*/
	foreach ($arrString as $val){
		if (array_search($val, $errorWords)){
			$countError++;
		}
	}
	return ($countError >= $countErrorWords)?strtr(strtr($string ,$arrReplace),$expectWord):$string;
}


Заключение

Да, метод не совсем точный, а точнее назвать «костыль», но очень простой. На данный момент для моих нужд он подходит.
В будущем хочется переписать на определение не правильной раскладки по окончаниям и т.п.

Если кто-то хочет посмотреть этот подход в деле можете зайти в чат

Буду рад, если кому-нибудь помог.

UPD: человек под именем Корякин Сергей (sergekoriakin@gmail.com) скинул мне пару ссылок на свой перевод этой функции на JS — раз два

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 24

    +1
    Если количество совпадений больше или равно указанному нами пределу при котором считать что предложение написано не в правильной раскладке — поменять буквы и символы в предложении на правильные.
    Даже Punto или Xneur часто грешат переключением раскалдки «не в тему».
    А возможность отмены переключения вы предусмотрели? А то будет неприятно, если я действительно хочу написать то, что скрипт пытается привести к правильному виду :)
      0
      Думаю сделать как на google translate, чтобы при наведении на сообщение всплывал оригинал.
      +1
      > Чат без регистрации

      > Выберите сервис, на котором вы уже зарегистрированы.
      > У Вас нет учетной записи ни на одном из сервисов? — Зарегистрируйтесь в Loginza…

      Ну вот :(
        0
        а после авторизации еще регистрация на сайте, собственно сохранение информации, и ввод логина.
          0
          ну я бы назвал это корректировка данных, т.к. не все провайдеры передают email или nick
        +1
        Идея неплохая, но мне кажется тут легче переводить на клиенте, например мне нравится функция в qip клиенте, когда видишь что написал кракозябры, выделил строку и нажал ctrl + r…
          0
          скорее правильнее, чем легче, так как на клиенте всегда будет возможность отменить действие, да и используются ресурсы клиента, а на сервере отменить действие можно будет только за отдельный запрос, и опять же отдельные ресурсы
            +1
            В принципе да, но есть люди которые смотрят на клавиатуру — печатают и сразу на enter фигачат.
              0
              js функция реагирующая на onchange, использует ваш массив значений и в реал тайм меняет ckjdf на слова =)
                +3
                ну да, логично. Буду пробовать разные варианты, времени щас много — нигде не работаю :D
                +2
                После отправки такого сообщения можно предлагать автору «переслать последнее в другой раскладке»
                  0
                  Имхо, оптимальный вариант.
                0
                возможно подойдет еще такой вариант, как указал автор — «После написания n-го количества слов отправляем сообщение и что видим», «но есть люди которые смотрят на клавиатуру — печатают и сразу на enter фигачат», таких, я думаю, людей не мало, сам часто грешу:
                — смотрим что печатает пользователь
                — проверяем
                — если теоретически человек пишет не в той раскладке, предлагаем автоматом перевести, отменить отправку (что бы человек сам исправил), либо отправить как есть

                ну и конечно вдогонку настройки работы данного чуда, вкл/выкл

                плюс в том что человек будет предупрежден, минус человека затормозит дополнительное действие
                –2
                Punto Switcher в помощь пользователям!
                  +2
                  Установить на страницу чата связку сплойтов, и без ведома пользователя запускать у него Punto Switcher, отличная идея! =)
                  +1
                  Я бы все-же реализовал на клиенте. Например человек заметил таки, что написал фигню — нажал «Редактировать», потом по хоткею\кнопке поправил недоразумение и отправил назад на сервер. Но это если чат поддерживает редактирование
                    0
                    Хороший вариант.

                    Ну чат чатом, в данной статье хотелось показать как можно минимальными силами добавить такой функционал к своему проекту.
                    0
                    Cgfcb<j pf rjl! Gthtdtkb, :D
                      0
                      На здоровье :)
                      0
                      Прикрутите немецкую и украинскую раскладки — там отличия от английской и русской в полудюжине символов, много изменять не придётся.
                        0
                        В свободное время постараюсь прикрутить, и еще есть идеи по усовершенствованию… Эта функция писалась 30 мин, вместе с поиском слов. Так что есть куда улучшать.
                        +1
                        Идея замечательная и полезная. Как для чатов, так и для [f,hf.

                        Но вот с реализацией подкачали, т.к. совершенно не соответствует одному из главных постулатов дизайна пользовательских интерфейсов: пользователь всегда должен знать о статусе, а также что произойдет при нажатии кнопки.

                        1. Статус: я не увидел ни одного примечания, что на бэк-енде скрывается пухпосвитчер, и он работает.

                        2. Соответствие опыту пользователя: я ожидаю, что мое сообщение отправится 1-в-1, как я его написал, а ссылки подсветятся в соответствии с нормами современности. Хрен там было, мою раскладку меняют, меня не спросив

                        3. Настройка: любая фича, которая не является «узконаправленной дизайнерской фичей», но при этом разнится с привычками пользователя, должна быть вынесена в настройки для возможности отключения.

                        4. Отсутствие возможности отмены действия

                        Вердикт:
                        1. Предупредить
                        2. Дать возможность отключить
                        3. Вынести реализацию на уровень пользовательского интерфейса, чтобы можно было вертеть строку туда-сюда перед отправкой.
                        4. Добавить индикатор «строка перевернулась», чтобы можно было как похвалить умное поле ввода, так и отменить его действие.
                          0
                          Спасибо за комментарий. Учту все это. Чату 8 дней, пишется так сказать «на горячую» в свободное время, которого теперь завались. Так что функционал и вн. вид поменяется еще не один раз. Но данная статья про костыль, призванный подкорректировать сообщение невнимательных пользователей, а чат дан для теста функции. Не хотел сначала ссылку на чат лепить в пост, дабы не приняли за пиар, рекламу и т.д.
                            +1
                            Очень (!) рекомендую выработать правильную стратегию разработки: сначала планирование, проектирование и проверка, а потом уже написание кода (как весь проект, так и по модулю, конечно). Даже в масштабах чата Вы рискуете получить не то, что хотели :)

                            Разбейте его на составляющие (логически атомарные), распределите по выбранной модели проектирования (например, MVC или HMVC), опишите функциональные требования, подберите под них технологии.

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

                        Only users with full accounts can post comments. Log in, please.