【问题标题】:How to use Perl's Text::Aspell to spellcheck a text?如何使用 Perl 的 Text::Aspell 对文本进行拼写检查?
【发布时间】:2021-11-25 09:01:24
【问题描述】:

我想在我的 Perl 程序中添加拼写检查。看起来Text::Aspell 应该可以满足我的需要,但它只提供了检查单个单词的功能。

use strict;
use warnings;
use Text::Aspell;

my $input = "This doesn't look too bad. Me&you. with/without. 1..2..3..go!";
my $aspell = Text::Aspell->new();
$aspell->set_option('lang', 'en');
print "$input: ", $aspell->check($input), "\n";

打印出来:

This doesn't look too bad. Me&you. with/without. 1..2..3..go!: 0

很明显它只需要单个单词,那么我如何将文本分成单词?一个简单的split 在空白处:

foreach my $word (split /\s/, $input) {
    next unless($word =~ /\w/);
    print "$word: ", $aspell->check($word), "\n";
}

这会导致没有空格的标点符号出现问题:

This: 1
doesn't: 1
look: 1
too: 1
bad.: 0
Me&you.: 0
with/without.: 0
1..2..3..go!: 0

我想我可以提一下标点符号:

foreach my $word (split qr{[,.;!:\s#"\?&%@\(\)\[\]/\d]}, $input) {
    next unless($word =~ /\w/);
    print "$word: ", $aspell->check($word), "\n";
}

这会得到合理的输出:

This: 1
doesn't: 1
look: 1
too: 1
bad: 1
Me: 1
you: 1
with: 1
without: 1
go: 1

但看起来很笨拙,我想知道是否有更简单(我要编写的代码更少,不那么脆弱)的方式。

如何对文本进行拼写检查?

【问题讨论】:

    标签: perl spell-checking aspell


    【解决方案1】:

    Text::Aspell 没有检查整个字符串的选项,而是只检查单个单词。我建议不要自己拆分字符串,而是使用已经为您执行此操作的模块,例如Text::SpellChecker。例如:

    use strict;
    use warnings;
    use Text::SpellChecker;
    use feature 'say';
    
    my $input = "This doesn't look too bad. Me&you. with/without. 1..2..3..go!";
    my $checker = Text::SpellChecker->new(text => $input);
    $checker->set_options(aspell => { 'lang' => 'en' });
    
    while (my $word = $checker->next_word) {
        say "Invalid word: $word";
    }
    

    或者,

    my $checker = Text::SpellChecker->new(text => $input);
    $checker->set_options(aspell => { 'lang' => 'en' });
    
    if ($checker->next_word) {
        say "The string is not valid.";
    } else {
        say "The string is valid.";
    }
    

    模块的documentation 展示了如何以交互方式替换错误的单词:

    while (my $word = $checker->next_word) {
        print $checker->highlighted_text, 
            "\n", 
            "$word : ",
            (join "\t", @{$checker->suggestions}),
            "\nChoose a new word : ";
        chomp (my $new_word = <STDIN>);
        $checker->replace(new_word => $new_word) if $new_word;
    }
    

    如果您想单独检查输入字符串的每个单词,您可以查看Text::SpellCheck 如何将字符串拆分为单词(这是由next_word 函数完成的)。它使用以下正则表达式:

    while ($self->{text} =~ m/\b(\p{L}+(?:'\p{L}+)?)/g) { 
        ...
    }
    

    【讨论】:

      【解决方案2】:

      以下代码 sn-p 使用不包含字母的正则表达式和' 将句子拆分为单词。

      你可以扩展正则表达式你的心愿。

      use strict;
      use warnings;
      
      use Text::Aspell;
      
      my $regex = qr/[^'a-z]+/i;
      my $input = "This doesn't look too bad. Me&you. with/without. 1..2..3..go!";
      my $aspell = Text::Aspell->new();
      
      $aspell->set_option('lang', 'en');
      
      printf "%12s: %d\n", $_, $aspell->check($_) for split($regex, $input);
      

      输出

              This: 1
           doesn't: 1
              look: 1
               too: 1
               bad: 1
                Me: 1
               you: 1
              with: 1
           without: 1
                go: 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-22
        • 1970-01-01
        • 1970-01-01
        • 2011-07-30
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        相关资源
        最近更新 更多