Доброго времени суток, на днях потребовалось проверить орфографию сразу большого числа статей. Проверить орфографию в ручную как-то неохотно, ну и тут я вспомнил что имею некоторые навыки программирования на Delphi и решил накатать простенькую десктопную программу, которая бы проверила необходимые мне статьи на орфографию. Данный пост и будет посвящён написанию подобной программы. Сразу хочу заметить, что помимо проверки, программа на автомате будет исправлять ошибки. Конечно, при подобном алгоритме с учётом машинной проверки и исправлений — могут быть допущены ошибки, но чтож поделать, всё лучше чем сидеть и проверять в ручную.
Для демонстрации работы с API yandex.speller разберём подобную программу, но с чуть меньшим функционалом — обойдёмся проверкой определённого текста статьи который будет браться из небольшого текстового поля. А вот и то, что мы наваяем сегодня:
Да, назовём нашу программу ‘очепятка’. Как видим интерфейс простенький — две кнопки, текстовое поле и несколько лейблов. Запускаем Delphi, создаём проект и кидаем эти компоненты — button, richedit (можно и мемо, но мы будем ‘разукрашивать’ наши слова которые исправили) ну и label. Но прежде чем мы приступим, если вы занимаетесь химическими исследованиями крови, то возможно вас заинтересует биохимический анализатор от Итнермедики который бесспорно должен быть в любой лаборатории по анализу крови. Ладно, едем дальше.
Проверка орфографии — программная часть, код Delphi
Проект создали, растаскали компоненты примерно как выше на скрине, теперь событие onclick первой кнопки ‘проверить’ код
var ts:tstringlist; XMLDocument1:tXMLDocument; word,s:string; SpellResult:IXMLNode; i, j:integer; begin XMLDocument1:=tXMLDocument.Create(form1); XMLDocument1.Active:=true; ts:=tstringlist.create(); ts.add('text='+ansitoutf8(richedit1.text)); memo1.lines.text:=idhttp1.Post('http://speller.yandex.net/services/spellservice/checkText',ts); memo1.lines.SaveToFile('xml.txt'); XMLDocument1.LoadFromFile('xml.txt'); j:=XMLDocument1.DocumentElement.ChildNodes.Count; label7.caption:='Ошибок в тексте: '+inttostr(XMLDocument1.DocumentElement.ChildNodes.Count); // Исправления ошибок for i:=0 to XMLDocument1.DocumentElement.ChildNodes.Count-1 do begin word:=XMLDocument1.DocumentElement.ChildNodes[I].ChildNodes['word'].text; s:=XMLDocument1.DocumentElement.ChildNodes[I].ChildNodes['s'].text; if s <> '' then // если есть варианты исправления, то исправляем richedit1.text:=StringReplace(richedit1.text, word, s, [rfReplaceAll, rfIgnoreCase]) else // в противном случае j:=j-1; // из общего числа ошибок вычитаем единицу end; label1.caption:='Исправлено: '+inttostr(j); //выделяем красным шрифтом слова, где были найдены ошибки for i:=0 to XMLDocument1.DocumentElement.ChildNodes.Count-1 do begin j:=XMLDocument1.DocumentElement.ChildNodes[i].Attributes['pos']; RichEdit1.SetFocus; RichEdit1.SelStart:=XMLDocument1.DocumentElement.ChildNodes[i].Attributes['pos']; Richedit1.SelLength:=XMLDocument1.DocumentElement.ChildNodes[i].Attributes['len']; RichEdit1.SelAttributes.Color:=clRed; memo1.SetFocus;
Теперь будем разбираться что мы накатали. Прежде всего, осуществлять проверку мы будем с помощью Яндекс.спеллер и их ‘Web Service API’. Нам необходимо послать на xml интерфейс текст, в ответ получим xml документ который содержит все ошибки/исправления к ним, а так же позиция начала слова с ошибкой и его длина. В коде легко разобраться, объясню основную часть
ts.add('text='+ansitoutf8(richedit1.text)); memo1.lines.text:=idhttp1.Post('http://speller.yandex.net/services/spellservice/checkText',ts);
здесь мы tstring пихаем наш проверяемый текст присваивая его переменной text, затем отсылаем методом POST эти данные Яндекс.спеллеру.
// Исправления ошибок for i:=0 to XMLDocument1.DocumentElement.ChildNodes.Count-1 do begin word:=XMLDocument1.DocumentElement.ChildNodes[I].ChildNodes['word'].text; s:=XMLDocument1.DocumentElement.ChildNodes[I].ChildNodes['s'].text; if s <> '' then // если есть варианты исправления, то исправляем richedit1.text:=StringReplace(richedit1.text, word, s, [rfReplaceAll, rfIgnoreCase]) else // в противном случае j:=j-1; // из общего числа ошибок вычитаем единицу end; label1.caption:='Исправлено: '+inttostr(j);
Второй по важности код — разбор XML ответа, проходим в цикле for по нашим ошибкам и исправляем их. В word хранится слово которое необходимо исправить, в s правильное слово. Заменяем слово ошибкой на правильное функцией StringReplace (дабы уж сразу всё исправить), а так же делаем проверку на пустое значение с правильным написанием слово, да, Яндекс тоже не очень обучен, хоть и видит что слово написано не правильно. Чуть не забыл, для вывода статистики тут так же присутствует переменная j, которая отвечает за исправленные ошибки. Чуть выше цикла в эту переменную мы кладём общее число ошибок, а в цикле вычитаем единицу каждый раз, когда нету варианта исправления, то есть когда строка s пустая.
Следующий цикл — раскраска текста, точнее слов которые написаны с ошибкой. Алгоритм простой, так же в цикле проходимся по всем словам, выдираем из xml ответа позицию слова и длину, затем выделяем это слово (RichEdit1.SelStart / Richedit1.SelLength) и указываем цвет, в нашем случае это clRed а-ля красный. На этом в принципе всё, скачать исходник программы а так же скомпилированную версию можно тут. К слову, при раскраске есть некоторые нюансы, а именно — слово с ошибкой не всегда может быть такой же длиной как и правильное, посему выделение может быть кривым. Исправляется это путём подсчёта общего кол-ва текста, сам алгоритм объяснять не буду, но если кому надо — велком в комментарии.
Эта прога существует? хотелось бы скачать потестить.