Проверка орфографии в тексте UTF-8 с помощью класса HunSpellChecker
Я пытаюсь проверять правописание строк, используя класс HunSpellChecker (см. http://www.phpkode.com/source/s/php-spell-checker/php-spell-checker/HunSpellChecker.class.php) и правописание hunspell. двигатель. Соответствующая функция скопирована здесь:
public function checkSpelling ($text, $locale, $suggestions = true) {
$text = trim($text);
if ($this->textIsHtml == true) {
$text = strtr($text, "\n", ' ');
} elseif ($text == "") {
$this->spellingWarnings[] = array(self::SPELLING_WARNING__TEXT_EMPTY=>"Text empty");
return false;
}
$descspec = array(
0=>array('pipe', 'r'),
1=>array('pipe', 'w'),
2=>array('pipe', 'w')
);
$pipes = array();
$cmd = $this->hunspellPath;
$cmd .= ($this->textIsHtml) ? " -H ":"";
$cmd .= " -d ".dirname(__FILE__)."/dictionaries/hunspell/".$locale;
$process = proc_open($cmd, $descspec, $pipes);
if (!is_resource($process)) {
$this->spellingError[] = array(self::SPELLING_ERROR__INTERNAL_ERROR=>"Hunspell process could not be created.");
return false;
}
fwrite($pipes[0], $text);
fclose($pipes[0]);
$out = '';
while (!feof($pipes[1])) {
$out .= fread($pipes[1], 4096);
}
fclose($pipes[1]);
// check for errors
$err = '';
while (!feof($pipes[2])) {
$err .= fread($pipes[2], 4096);
}
if ($err != '') {
$this->spellingError[] = array(self::SPELLING_ERROR__INTERNAL_ERROR=>"Spell checking error: ".$err);
fclose($pipes[2]);
return false;
}
fclose($pipes[2]);
proc_close($process);
if (strlen($out) === 0) {
$this->spellingError[] = array(self::SPELLING_WARNING__EMPTY_RESULT=>"Empty result");
return false;
}
return $this->parseHunspellOutput(explode("\n", $out), $locale, $suggestions);
}
Он хорошо работает со строками ASCII, но я должен проверять строки на разных языках, в которых есть символы с акцентом (нужное, segurança и т. Д.) Или они имеют нелатинский алфавит (греческий, арабский и т. Д.).
Проблема в этих случаях заключается в том, что слова, не входящие в ASCII, сегментированы неправильно, и слово с ошибкой, отправленное Hunspell, на самом деле является подстрокой, а не полным словом (need, seguran).
Я попытался отследить, где возникает проблема, и я предполагаю, что она должна быть в строке 072 класса, указанного выше, когда строка преобразуется в ресурс (или где-то после этого). Строка 072 содержит:
fwrite ($ pipe [0], $text);
Класс не комментируется, поэтому я не совсем уверен, что там происходит.
Кто-нибудь имел дело с подобными проблемами, или кто-то может оказать какую-либо помощь?
Этот класс включен в файл examples/HunspellBased.php (пакет загружен с http://titirit.users.phpclasses.org/package/5597-PHP-Check-spelling-of-text-and-get-fix-suggestions.html). Я пытался использовать Enchant, но мне не удалось заставить его работать вообще.
Спасибо! Ура, Мануэль
2 ответа
Я думаю, что вы можете добавить после:
$cmd = $this->hunspellPath;
$cmd .= ($this->textIsHtml) ? " -H ":"";
$cmd .= " -d ".dirname(__FILE__)."/dictionaries/hunspell/".$locale;
добавлять
$cmd .= " -i UTF-8";
Я думаю, что ваша проблема либо в HTML-сущностях, либо в файлах словаря.
Используя ваш пример со словарем португальского языка, загруженным из дополнений Mozilla, я могу воспроизвести вашу проблему только при использовании HTML-кодированных объектов. т.е. segurança
хорошо, но segurança
получить сегментировано, как вы говорите.
Я не думаю, что это проблема с классом. Все, что делает класс, это передает текст в программу командной строки. Вы можете устранить класс PHP как проблему, используя программу напрямую следующим образом:
Измените рабочий каталог на место, где у вас есть словари, php-spell-checker/dictionaries/hunspell
в соответствии с вашим кодом выше. Подготовьте текстовый файл с акцентированными словами, которые вы хотите протестировать, а затем выполните:
hunspell -l -d pt-PT test.text
или для HTML:
hunspell -l -d pt-PT -H test.html
куда pt_PT
представляет имя пары файлов португальского словаря, а именно pt-PT.aff
а также pt–PT.dic
Отсутствие вывода означает отсутствие ошибок. Если вы получаете частичные слова, такие как "need", только при использовании HTML-сущностей, тогда это ваша проблема. Если нет, то это либо другая проблема с кодировкой строк, либо проблема со словарем, который вы используете.
Я подозреваю, что это ограничение HTML-парсера hunspell - он игнорирует HTML-теги и другие прерывистые объекты, но не включает и не декодирует слово с объектом в середине.
Единственный способ обойти это (предполагая, что HTML - это ваша проблема) - выполнить собственную предварительную обработку перед отправкой HTML на проверку орфографии. РНР html_entity_decode
преобразует ç -> ç
так что вы можете попробовать вызывать это в каждой строке. В идеале, хотя бы вы анализируете HTML DOM и извлекаете только текстовые узлы.
Если HTML не является вашей проблемой, убедитесь, что строки являются допустимыми UTF-8.
В противном случае попробуйте другой файл словаря. Тот, который я взял от Mozilla, отлично работает с простым текстом. Просто переименуйте .xpi
подать в .gzip
разверните его, используя любое программное обеспечение для распаковки, затем скопируйте .dic
а также .aff
файлы в папку словаря.