Кодинг: найти буквы-шпионы

ijk
На сайте с 19.08.2007
Offline
199
ijk
983

Столкнулся с такой ситуацией. При копировании текста из web.archive.org в некоторых словах одна или несколько русских букв заменены латинскими с идентичным написанием. Например, p – р, H – Н, c – с.

Возникла задача автоматически лажу в тексте поправить.

Алгоритм

1. Делаем split с соответствующим regex’ом, чтобы вычленить из текста слова, отделив теги, числа и пунктуацию.

2. Для каждого слова считаем количество русских и английских букв в нём.

3. Если количество и русских и английских букв в слове больше нуля, при этом количество английских букв не больше, чем количеств русских – печатаем слово и буквы-шпионы (написанные латиницей). На этом шаге нужен контроль человека. Смотрим, что слова и вправду “кривые” и добавляем в код соответствующие замены.

4. Складываем в ассоциативный массив (в моём случае HashMap) пары “кривое слово” – “правильный аналог”.

5. Бежим по массиву ключей и заменяем в тексте все кривые слова на правильные аналоги.

А как бы вы стали решать такую задачу?

Оригинал: Кодинг: найти буквы-шпионы

T.R.O.N
На сайте с 18.05.2004
Offline
314
#1

ijk, Как много у Вас английских слов на сайте? Если очень много, то вопрос имеет смысл. Если нет - простая замена.

Если нужно именно анализировать - возможны ли ситуации, при которых рус и англ буквы стоят рядом?

Обрабатываем весь файл посимвольно, игнорируя тэги. Можно использовать парсер. Как только нашли англ букву смотрим есть ли русские буквы от начала слова до этого места и от этого места до конца слова. Если есть - меняем англ на рус. Вот и все. Без массивов и прочего.

От воздержания пока никто не умер. Хотя никто и не родился! Prototype.js был написан теми, кто не знает JavaScript, для тех, кто не знает JavaScript (Richard Cornford)
[umka]
На сайте с 25.05.2008
Offline
456
#2

Как-то вот так ... примерно ... не проверял :)

$replace=array('p'=>'р','H'=>'Н','c'=>'с');

$data=preg_replace('/([А-Яа-я\b])(['.implode(array_keys($replace)).'])([А-Яа-я\b])/e',"'\\1'.\$replace['\\2'].'\\3'");

массив $replace дополняем нужными буквами

Лог в помощь!
ijk
На сайте с 19.08.2007
Offline
199
ijk
#3
T.R.O.N:
ijk, Как много у Вас английских слов на сайте? Если очень много, то вопрос имеет смысл. Если нет - простая замена.

Если нужно именно анализировать - возможны ли ситуации, при которых рус и англ буквы стоят рядом?

Конечно. Например слово "HTMLка". А есть ещё слово "Z-буфер", где вся моя теория падает. Поэтому предпочёл кривые слова просматривать вручную.

T.R.O.N:
Обрабатываем весь файл посимвольно, игнорируя тэги. Можно использовать парсер. Как только нашли англ букву смотрим есть ли русские буквы от начала слова до этого места и от этого места до конца слова. Если есть - меняем англ на рус. Вот и все. Без массивов и прочего.

Как вариант. Но мой, ИМХО, проще.

ijk добавил 25.11.2010 в 21:19

'[umka:
;8056820']Как-то вот так ... примерно ... не проверял :)
$replace=array('p'=>'р','H'=>'Н','c'=>'с');
$data=preg_replace('/([А-Яа-я\b])(['.implode(array_keys($replace)).'])([А-Яа-я\b])/e',"'\\1'.\$replace['\\2'].'\\3'");

массив $replace дополняем нужными буквами

Вариант. Но тут в чем загвоздка - идёт слепая замена. Это раз. Непонятно, какие именно буквы являются шпионами. Это два. Да и не факт, что буква-шпион в слове одна (хотя в моём случае было именно так).

В любом случае спасибо за regex.

T.R.O.N
На сайте с 18.05.2004
Offline
314
#4
ijk:
Например слово "HTMLка"

Мой вариант не прокатит, хотя можно сделать анализ больших.

ijk:
"Z-буфер"

Мой вариант сработает.

ijk:
Как вариант. Но мой, ИМХО, проще.

Вы считаете что вариант с массивами + человек проще чем 3-4 строчки кода?

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий