Проверка орфографии в тексте 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 файлы в папку словаря.

Другие вопросы по тегам