
Для начала, попробуем разобраться в том, из чего, собственно, состоят грамматические пакеты в OO. В качестве примера, разберем файлы грамматики русского языка. С сайта ОО скачиваем архив с языковым пакетом грамматики. Внутри архива мы найдем три файла: readme.txt, ru_RU.dic, ru_RU.aff. С Readme все понятно – при необходимости его можно прочитать. Файл с расширением dic – представляет собой словарь со словами, которые встречаются в русском языке. Естественно, там не все слова, и его необходимо будет пополнять. Второй файлик с расширением AFF, представляет собой файл грамматики. Формат этого файла будет либо MySpell либо Aspell. В любом случае, он подойдет для нашего модуля.
Теперь, когда мы разобрались с форматами этих файлов, приступим к самому модулю. Для него нам понадобится Hunspell API, которую можно взять во ссылке внизу статьи. API написана другим разработчиком и подходит для самой примитивной проверки грамматики. Писать будем на Java. Для тестов, мы напишем простой сервлет, который будет получать слово в качестве параметра, проверять его, и возвращать нам исправленный результат, если слово неправильно написано. О том, как создать WEB-приложение в среде Java, написано очень много статей, поэтому на этом особо останавливаться не будем. Начнем сразу же с самого главного. Сделаем небольшую форму, состоящую из поля для ввода и кнопки:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <form method="POST" action="http://localhost:8080/SpellChecker/spellChecker"> <input type="text" name="input"/> <input type="submit" name="submit"/> </form> </body> </html>
Теперь, сделаем непосредственно сам сервлет. В сервлете мы будем получать данные из формы, отправлять их в библиотеку Hunspell, обрабатывать ответ, и отсылать обратно на форму. Рассмотрим методы, которые это будут делать:
1. protected void processRequest(HttpServletRequest request, HttpServletResponse response) 2. throws ServletException, IOException { 3. response.setContentType("text/html;charset=UTF-8"); 4. PrintWriter out = response.getWriter(); 5. try { 6. String input = request.getParameter("input"); 7. List<String> list = check(input); 8. request.setAttribute("output", list); 9. Iterator iter = list.iterator(); 10. while (iter.hasNext()) { 11. out.println((String) iter.next()); 12. } 13. 14. } finally { 15. out.close(); 16. } 17.}
Рассмотрим все поэтапно:
1 и 2 строки объявляют функцию, которая обрабатывает запрос. На 3 строке в ответ мы ставим, что тип результата будет HTML страница с кодировкой UTF-8, дабы избежать недоразумений со специальными символами(диактрические знаки). Далее, на 4 строке, инициализируем контейнер для вывода данных, и открываем поток. Тут уже начинается самое интересное. Параметр, расположенный на 6 строке, содержит входные данные, тоесть слово, которое нужно проверить на грамматику. Передаем его в функцию check(String string), которую мы разберем позже. Вкратце скажу, что эта функция проверяет наше слово на ошибки, и в качестве ответа предоставляет список с исправлениями. После этого, мы итерируем по списку исправлений(9-12 строка), и выводим этот список в поток, тоесть, выводим список на экран. На 15 строке закрываем поток.
1.public List<String> check(String input) { 2. List<String> list = new ArrayList(); 3. List<String> stemList = new ArrayList(); 4. try { 5. String newInput = ""; 6. if (input != null) { 7. newInput = new String(input.getBytes("ISO-8859-1"), "UTF-8"); 8. } 9. Hunspell hunspell = Hunspell.getInstance(); 10. Dictionary dict = hunspell.getDictionary("ru-RU"); 11. if (dict.misspelled(newInput)) { 12. list = dict.suggest(newInput); 13. } else { 14. list.add(newInput); 15. } 16. 17. } catch (FileNotFoundException ex) { 18. Logger.getLogger(spellChecker.class.getName()).log(Level.SEVERE, null, ex); 19. } catch (UnsupportedEncodingException ex) { 20. Logger.getLogger(spellChecker.class.getName()).log(Level.SEVERE, null, ex); 21. } 22. list.addAll(stemList); 23. return list; 24. }
А вот и сама функция check(String string). На 2 и 3 строках делаем два новых списка. В первый будем вставлять окончательный результат, а второй используем в качестве временного буфера. Строки 5-8 кодируют наш запрос в UTF-8, потому что словарь понимает только такую кодировку. На 9 строке инициализируем Hunspell, а на 10 указываем, какой словарь будем использовать. В данном случае, это русский словарь. Файлы проверки грамматики(ru_RU.dic, ru_RU.aff) должны быть в том же каталоге, что и программа, поэтому не забудем их туда перенести. Далее(11 строка) идет проверка на то, правильно ли написано слово. Если слово написано неправильно(11-13), то мы получаем результаты того, как правильно нужно написать это слово. Если же слово написано правильно(13-15), то возвращаем его обратно. Все предельно просто и кратко. Строки с 17 по 21 являются обработчиками ошибок. Первая обработка (FileNotFoundException) идет на отсутствие файлов грамматики, а вторая (UnsupportedEncodingException) относится к функции, которая кодирует наш запрос в UTF-8, и обрабатывает подержку кодировки. На 22 строке переносим все из временного буфера(stemList) в результат(list), и на 23 строке возвращаем его.
Напомню еще раз, что нужно перенести файлы AFF и DIC в папку с приложением, дабы программа могла их задействовать. Если же это сделать нельзя, то можно указать полный путь до словаря в 10 строке. Расширение указывать не нужно.
При желании, этот сервлет можно переделать в небольшой сервис, который будет общаться через XML. Подключить к нему больше языков Hunspell, которые распространяются бесплатно, и постоянно пополняются. Также, можно подключить библиотеку распознавания языков, о которой я расскажу в следующей статье.
Теперь поделюсь с вами ссылками, где же можно взять все это добро:
Hunspell API — dren.dk/hunspell.html
Словари OpenOffice — wiki.services.openoffice.org/wiki/Dictionaries
Также, словари можно взять на страницах разработчиков. Там они гораздо «свежее».