0

我正在检查这个搬运工词干分析器。下面他们说我应该改变我的第一行。我到底做了什么,但词干分析器不起作用。一个好的例子可能是什么?

#!/usr/local/bin/perl -w
#
# Perl implementation of the porter stemming algorithm
# described in the paper: "An algorithm for suffix stripping, M F Porter"
# http://www.muscat.com/~martin/stem.html
#
# Daniel van Balen (vdaniel@ldc.usb.ve)
#
# October-1999
#
# To Use:
#
# Put the line "use porter;" in your code. This will import the subroutine 
# porter into your current name space (by default this is Main:: ). Make 
# sure this file, "porter.pm" is in your @INC path (it includes the current
# directory).
# Afterwards use by calling "porter(<word>)" where <word> is the word to strip.
# The stripped word will be the returned value.
#
# REMEMBER TO CHANGE THE FIRST LINE TO POINT TO THE PATH TO YOUR PERL 
# BINARY
#

作为代码,我正在编写以下内容:

use Lingua::StopWords qw(getStopWords);
use Main::porter;
my $stopwords = getStopWords('en');

@stopwords = grep { $stopwords->{$_} } (keys %$stopwords);

    chdir("c:/perl/input");
    @files = <*>;
    foreach $file (@files) 
      {
        open (input, $file);

        while (<input>) 
          {
            open (output,">>c:/perl/normalized/".$file);
        chomp;
        porter<$_>;
        for my $stop (@stopwords) 
        {
        s/\b\Q$stop\E\b//ig;
        }
        $_ =~s/<[^>]*>//g;
        $_ =~ s/[[:punct:]]//g;
        print output "$_\n";

          }

       }
    close (input);
    close (output);

该代码没有给出任何错误,只是它没有阻止任何东西!!!

4

1 回答 1

4

该评论块充满了不正确的建议。

一个 #!.pm 文件中的行无效。这是一个常见的错误。这 #!当且仅当您将文件作为命令行程序运行时,行告诉 Unix 使用哪个解释器运行程序。

./somefile                # uses #! to determine what to run somefile with
/usr/bin/perl somefile    # runs somefile with /usr/bin/perl regardless of #!

这 #!行在一个模块中什么都不做,一个 .pm 文件,你use. 那时 Perl 已经在运行了。该行只是一个注释。

第二个问题是您的默认命名空间main不是Main. 外壳很重要。

继续您的代码,use Main::porter;不应该工作。应该是use porter。您应该会收到一条错误消息,例如Can't locate Main/porter.pm in @INC (@INC contains: ...). 如果该代码运行,也许您将 porter.pm 移到了一个Main/目录中?移出来,会混淆porter函数的导入。

porter<$_>;说“尝试从文件句柄 $_ 中读取一行并将其传递给搬运工”。$_ 不是文件句柄,它是您刚刚打开的文件中的一行。您想porter($_)将该行传递给 porter 函数。如果你打开警告(添加use warnings到你的脚本顶部)Perl 会警告你这样的错误。

您可能还想对 porter 的返回值做一些事情,否则它真的什么都不做。 my @whatever_porter_returns = porter($_).

您的一个或多个可能chdir已经open默默地失败了,因此您的程序可能没有输入。不幸的是,Perl 不会让您知道何时发生这种情况,您必须检查一下。通常你在函数之后添加一个or die $!来检查错误。这是一项繁忙的工作,经常会忘记,相反,如果任何系统调用喜欢或失败,您可以use autodie自动产生错误。chdiropen

修复了这些东西后,您的代码应该可以工作,或者至少会产生有用的错误消息。

最后,CPAN 上有许多词干模块,它们的质量可能比您在文档、测试和更新等中找到的模块质量更高。 Lingua::StemText::English专门使用了 porter 算法。你可能想试一试。

于 2012-11-13T16:40:38.623 回答