我正在尝试使用HunSpellChecker类(见 https://web.archive.org/web/20130311163032/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 字符串,但我必须检查不同语言的字符串,这些字符串具有重音字符(necessário、segurança 等)或非拉丁字母(希腊语、阿拉伯语等)。
在这些情况下,问题在于非ASCII单词被错误地分割,并且发送到Hunspell的"拼写错误"单词实际上是一个子字符串而不是完整的单词(必要,seguran)。
我试图跟踪问题发生的位置,我认为当字符串转换为资源(或之后的某个地方)时,它必须在上面链接的类的第 072 行中。072行包含:
fwrite($pipes[0], $text);
该课程没有评论,所以我不太确定那里发生了什么。
有没有人处理过类似的问题,或者有人可以提供任何帮助吗?
该类包含在文件示例/HunspellBased.php(从 http://titirit.users.phpclasses.org/package/5597-PHP-Check-spelling-of-text-and-get-fix-suggestions.html 下载的包)中。我尝试使用Enchant,但我根本无法让它工作。
谢谢!干杯,曼努埃尔
我认为您的问题要么是 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
输出意味着无错误。如果您仅在使用 HTML 实体时收到诸如"必要"之类的部分词,那么这就是您的问题。如果不是,那么要么是其他类型的字符串编码问题,要么是您正在使用的字典的问题。
我怀疑这是 hunspell 的 HTML 解析器的一个限制 - 它忽略了 HTML 标签和其他标点符号实体,但不会包含和解码中间有实体的单词。
解决此问题的唯一方法(假设 HTML 是您的问题)是在将 HTML 发送到拼写检查之前进行自己的预处理。PHP 的 html_entity_decode
将转换ç -> ç
因此您可以尝试在每个字符串上调用它。理想情况下,尽管您会解析HTML DOM并仅提取文本节点。
如果 HTML 不是您的问题,请检查字符串是否有效 UTF-8。
如果失败,请尝试另一个字典文件。我从Mozilla抓取的那个在纯文本下工作得很好。只需将.xpi
文件重命名为.gzip
,使用您拥有的任何解压缩软件将其展开,然后将.dic
和.aff
文件复制到字典文件夹中。
我想你可以在之后添加:
$cmd = $this->hunspellPath;
$cmd .= ($this->textIsHtml) ? " -H ":"";
$cmd .= " -d ".dirname(__FILE__)."/dictionaries/hunspell/".$locale;
加
$cmd .= " -i UTF-8";