Perl与Aspell的接口

Perl与Aspell的接口,perl,aspell,Perl,Aspell,我试图通过Perl识别Aspell拼写错误的单词。我在没有管理员权限的Linux服务器上工作,这意味着我可以访问Perl和Aspell,但不能访问Text::Aspell,它是Aspell的Perl接口 我想做一个非常简单的任务,将单词列表传递给Aspell,并让它返回拼写错误的单词。如果我要检查的单词是“dad word lkjlkjj”,我可以使用以下命令通过命令行执行此操作: aspell list dad word lkjlkjlkj Aspell要求在末尾按CTRL+D组合键才能提交

我试图通过Perl识别Aspell拼写错误的单词。我在没有管理员权限的Linux服务器上工作,这意味着我可以访问Perl和Aspell,但不能访问Text::Aspell,它是Aspell的Perl接口

我想做一个非常简单的任务,将单词列表传递给Aspell,并让它返回拼写错误的单词。如果我要检查的单词是“dad word lkjlkjj”,我可以使用以下命令通过命令行执行此操作:

aspell list
dad word lkjlkjlkj
Aspell要求在末尾按CTRL+D组合键才能提交单词列表。然后它会返回“LKJLKJJ”,因为字典中没有这个

为了做完全相同的事情,但通过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=LKJLKJJ”,因为这是Aspell在通过命令行提交这些命令时给出的输出。但是,实际输出只是“Aspell output=”。也就是说,Perl不会捕获Aspell的任何输出。不会抛出任何错误


我不是一个专业的程序员,但我认为这将是一个相当简单的任务。我尝试过这段代码的各种迭代,但都没有效果。我做了一些挖掘,我担心可能因为Aspell是交互式的,我需要使用Expect之类的东西,但我不知道如何使用它。我也不确定这实际上是解决我问题的办法。我还认为^D应该是命令末尾CTRL+D的合适替代品,但我所知道的是它不会抛出错误。我也尝试了\cd。不管是什么,提交命令还是捕获输出都显然存在问题。

您应该后退一步,调查是否可以在没有管理员权限的情况下安装
Text::Aspell
。在大多数情况下,这是正确的


您可以将模块安装到主目录中。如果服务器上没有可用的C编译器,您可以将模块安装在兼容机器上,编译并复制文件。

在程序外使用
aspell
的复杂之处在于,正如您所怀疑的,它是一个交互式命令行驱动工具。但是,有一种简单的方法可以满足您的需要

要使用
aspell
的命令
list
,需要通过
STDIN
传递单词,如手册页所示。虽然我发现调用有点困难,但通过其
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

出于特定原因,我将命令汇编成字符串(而不是数组),如下所述。是backticks的操作符形式,我更喜欢它的可读性

请注意,
qx
可以返回字符串中的所有输出,如果是在标量上下文中(例如分配给标量),或者是在列表上下文中的列表中。在这里,我分配给一个数组,以便将每个单词作为一个元素(唉,每个单词都有一个换行符,因此可能需要执行
chomp@aspell\u;


命令的列表与字符串形式的注释

一般来说,我认为建议对命令使用列表形式是安全的。我们可以这么说

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
    操作符的行为并没有什么不同——数组被连接成一个字符串,然后运行。我们可以将其传递为数组这一事实是偶然的,甚至没有记录在案

  • 我们需要通过管道将输入传输到aspell的
    STDIN
    ,shell只为我们做了这件事。我们也可以将shell与命令的列表形式一起使用,但随后需要显式地调用它。我们也可以通过shell以外的方式使用
    aspell
    STDIN
    ,但这更复杂

  • 对于列表中的命令,命令名必须是第一个单词,因此问题中的
    “aspell list”
    是错误的,并且应该失败(没有名为该命令的命令)。。。除了在这种情况下它不会(如果其余的都是正确的),因为对于
    qx
    ,数组被折叠成一个字符串


最后,
apsell
在一个C库中很好地公开了它的API,您提到的模块已经使用了这个API。我建议以用户身份安装它(不需要特权)并使用它。

考虑hunspell库的界面,因为它维护得更好。这非常完美,非常感谢!我现在能让它工作了。帮助我理解通过STDIN提交命令的背景信息非常有用。@elci great:)如果出现问题,请告诉我know@elci将内容传递给外部程序的
STDIN
--1)将它们保存在文件中,然后运行
prog
(然后,
prog
通过其
STDIN
逐行读取文件)2)使用“管道打开”(参见文档)3)最好使用模块,例如或。当我有时间的时候,我会补充一下答案是的,这确实是最简单的解决方案,也是我第一次能够安装Aspell和其他Perl模块的原因,但是当我尝试安装Text::Aspell时,事情发展到了另一个层次。在这种特殊情况下,我认为,考虑到我们特定的服务器配置,找出如何直接使用Aspell比跳过安装Text::Aspell的多个步骤要简单得多。但是,是的,我同意总的来说,最好的解决办法总是尽量不要重新发明轮子!(: