Perl 与 Aspell 的接口
Perl interface with Aspell
我正在尝试通过 Perl 使用 Aspell 识别拼写错误的单词。我在没有管理员权限的 Linux 服务器上工作,这意味着我可以访问 Perl 和 Aspell,但不能访问 Text::Aspell,它是 Aspell 的 Perl 接口。
我想做一个非常简单的任务,将单词列表传递给 Aspell 并让它 return 拼错的单词。如果我要检查的单词是 "dad word lkjlkjlkj",我可以通过命令行使用以下命令执行此操作:
aspell list
dad word lkjlkjlkj
Aspell 要求最后按 CTRL + D 提交单词表。然后它将 return "lkjlkjlkj",因为这不在字典中。
为了做完全相同的事情,但通过 Perl 提交(因为我需要对数千个文档执行此操作)我已经尝试过:
my $list = q(dad word lkjlkjlkj):
my @arguments = ("aspell list", $list, "^D");
my $aspell_out=`@arguments`;
print "Aspell output = $aspell_out\n";
预期的输出是 "Aspell output = lkjlkjlkj",因为这是当您通过命令行提交这些命令时 Aspell 给出的输出。然而,实际输出只是"Aspell output = "。也就是说,Perl 不捕获 Aspell 的任何输出。没有抛出任何错误。
我不是专业的程序员,但我认为这将是一项相当简单的任务。我已经尝试了此代码的各种迭代,但没有任何效果。我做了一些挖掘,我担心也许因为 Aspell 是交互式的,我需要使用类似 Expect 的东西,但我不知道如何使用它。我也不确定它是否真的能解决我的问题。我还认为 ^D 应该是命令末尾 CTRL+D 的适当替代品,但我所知道的是它不会引发错误。我也尝试过 \cd 。无论是什么,提交命令或捕获输出显然都存在问题。
您应该退后一步,调查是否可以在没有管理员权限的情况下安装 Text::Aspell
。在大多数情况下是 perfectly possible.
您可以将模块安装到主目录中。如果服务器上没有可用的 C 编译器,您可以在兼容机器上安装模块,编译并复制文件。
从程序中使用 aspell
的复杂之处在于它是一个交互式命令行驱动程序工具,正如您所怀疑的那样。但是,有一种简单的方法可以满足您的需要。
为了使用 aspell
的命令 list
,需要通过 STDIN
向其传递文字,如其手册页所述。虽然我发现 GNU Aspell manual 有点难以上手,但通过它的 STDIN
将输入传递给程序很容易,我们可以将调用重写为
echo dad word lkj | aspell list
我们得到 lkj
回打印,如期。现在这可以 运行 出一个程序,就这样
my $word_list = q(word lkj good asdf);
my $cmd = qq(echo $word_list | aspell list);
my @aspell_out = qx($cmd);
print for @aspell_out;
这会打印行 lkj
和 asdf
。
I assemble 出于特定原因,命令在字符串(而不是数组)中,解释如下。 qx 是反引号的运算符形式,我更喜欢它,因为它的可读性要好得多。
注意 qx
可以 return 所有输出在一个字符串中,如果在 标量上下文 (例如分配给一个标量),或者在一个在 列表上下文 中列出。在这里,我分配给一个数组,这样你就可以将每个单词作为一个元素(唉,每个单词还带有一个换行符,所以可能需要 chomp @aspell_out;
)。
评论命令的列表与字符串形式
我认为通常建议对命令使用列表形式是安全的。所以我们会说
my @cmd = ('ls', '-l', $dir); # to be run as an external command
而不是
my $cmd = "ls -l $dir"; # to be run as an external command
列表形式通常更易于管理命令,并且完全避免了 shell。
然而,这个案例有点不同
qx
运算符的行为并没有真正不同——数组被连接成一个字符串,运行s。我们 可以 将数组传递给它这一事实是偶然的,甚至没有记录
我们需要管道输入到aspell
的STDIN
,shell为我们简单地完成了.我们也可以将 shell 与命令的 LIST 形式一起使用,但是我们需要明确地调用它。我们也可以通过 shell 以外的方式获得 aspell
的 STDIN
,但这更复杂
对于列表中的命令,命令名称必须是第一个单词,因此问题中的 "aspell list"
是错误的,它应该失败(没有命名的命令)...除了 在这种情况下 它不会(如果其余的都是正确的),因为对于 qx
数组被折叠变成一个字符串
最后,apsell
很好地在 C 库中公开了它的 API,并且已用于您提到的模块。我建议以用户身份安装它(不需要特权)并使用它。
我正在尝试通过 Perl 使用 Aspell 识别拼写错误的单词。我在没有管理员权限的 Linux 服务器上工作,这意味着我可以访问 Perl 和 Aspell,但不能访问 Text::Aspell,它是 Aspell 的 Perl 接口。
我想做一个非常简单的任务,将单词列表传递给 Aspell 并让它 return 拼错的单词。如果我要检查的单词是 "dad word lkjlkjlkj",我可以通过命令行使用以下命令执行此操作:
aspell list
dad word lkjlkjlkj
Aspell 要求最后按 CTRL + D 提交单词表。然后它将 return "lkjlkjlkj",因为这不在字典中。
为了做完全相同的事情,但通过 Perl 提交(因为我需要对数千个文档执行此操作)我已经尝试过:
my $list = q(dad word lkjlkjlkj):
my @arguments = ("aspell list", $list, "^D");
my $aspell_out=`@arguments`;
print "Aspell output = $aspell_out\n";
预期的输出是 "Aspell output = lkjlkjlkj",因为这是当您通过命令行提交这些命令时 Aspell 给出的输出。然而,实际输出只是"Aspell output = "。也就是说,Perl 不捕获 Aspell 的任何输出。没有抛出任何错误。
我不是专业的程序员,但我认为这将是一项相当简单的任务。我已经尝试了此代码的各种迭代,但没有任何效果。我做了一些挖掘,我担心也许因为 Aspell 是交互式的,我需要使用类似 Expect 的东西,但我不知道如何使用它。我也不确定它是否真的能解决我的问题。我还认为 ^D 应该是命令末尾 CTRL+D 的适当替代品,但我所知道的是它不会引发错误。我也尝试过 \cd 。无论是什么,提交命令或捕获输出显然都存在问题。
您应该退后一步,调查是否可以在没有管理员权限的情况下安装 Text::Aspell
。在大多数情况下是 perfectly possible.
您可以将模块安装到主目录中。如果服务器上没有可用的 C 编译器,您可以在兼容机器上安装模块,编译并复制文件。
从程序中使用 aspell
的复杂之处在于它是一个交互式命令行驱动程序工具,正如您所怀疑的那样。但是,有一种简单的方法可以满足您的需要。
为了使用 aspell
的命令 list
,需要通过 STDIN
向其传递文字,如其手册页所述。虽然我发现 GNU Aspell manual 有点难以上手,但通过它的 STDIN
将输入传递给程序很容易,我们可以将调用重写为
echo dad word lkj | aspell list
我们得到 lkj
回打印,如期。现在这可以 运行 出一个程序,就这样
my $word_list = q(word lkj good asdf);
my $cmd = qq(echo $word_list | aspell list);
my @aspell_out = qx($cmd);
print for @aspell_out;
这会打印行 lkj
和 asdf
。
I assemble 出于特定原因,命令在字符串(而不是数组)中,解释如下。 qx 是反引号的运算符形式,我更喜欢它,因为它的可读性要好得多。
注意 qx
可以 return 所有输出在一个字符串中,如果在 标量上下文 (例如分配给一个标量),或者在一个在 列表上下文 中列出。在这里,我分配给一个数组,这样你就可以将每个单词作为一个元素(唉,每个单词还带有一个换行符,所以可能需要 chomp @aspell_out;
)。
评论命令的列表与字符串形式
我认为通常建议对命令使用列表形式是安全的。所以我们会说
my @cmd = ('ls', '-l', $dir); # to be run as an external command
而不是
my $cmd = "ls -l $dir"; # to be run as an external command
列表形式通常更易于管理命令,并且完全避免了 shell。
然而,这个案例有点不同
qx
运算符的行为并没有真正不同——数组被连接成一个字符串,运行s。我们 可以 将数组传递给它这一事实是偶然的,甚至没有记录我们需要管道输入到
aspell
的STDIN
,shell为我们简单地完成了.我们也可以将 shell 与命令的 LIST 形式一起使用,但是我们需要明确地调用它。我们也可以通过 shell 以外的方式获得aspell
的STDIN
,但这更复杂对于列表中的命令,命令名称必须是第一个单词,因此问题中的
"aspell list"
是错误的,它应该失败(没有命名的命令)...除了 在这种情况下 它不会(如果其余的都是正确的),因为对于qx
数组被折叠变成一个字符串
最后,apsell
很好地在 C 库中公开了它的 API,并且已用于您提到的模块。我建议以用户身份安装它(不需要特权)并使用它。