如何使用grep查看数组中的单词是否与字典中的单词列表匹配并提取确切的单个单词?

时间:2009-10-01 16:22:27

标签: perl grep

感谢您的回答......我正在尝试所有答案的不同可能性。 一件事:我向你们所有人提问时我都不会那么清楚,即。我将这个RE应用于我的本地脚本/字符(类似于藏文脚本),而不是英文单词。

foreach my $word (@list)
{
  if(grep(/$word/, $dict))       # i have dict in scalar ($dict)
       {
           print "Matched and Found\n";
        }
    else
      {
         print "Not Matched\n";
      }
}

重点是提取单个匹配的精确单词。我尝试使用/ \ b $ word \ b / ...这似乎不适用于我们的脚本...我们的单词由多音节组成,每个音节用(。)(藏语Tsheg)分隔。

其他信息:

  

对于初学者来说,藏语句子最具挑战性的特征是单词之间缺乏分离。 ...由于单词之后没有空格,读者必须根据句子中的上下文和位置找出每个单词。在字典中查找这两个字母可能会让您认为这句话的开头是对地球表面的引用。然而,句子的其余部分,它的上下文以及缺少一个有用的案例连接符,表明这两个字母本身不是单词,而是“昨天”这个单词。从这里你可以看到,首先通过识别它的各种元素来评估一个句子是好的,而不是逐字逐句地翻译它。

重点补充。见http://www.learntibetan.net/grammar/sentence.htm

10 个答案:

答案 0 :(得分:3)

将字典保存在字符串中并使用grep搜索它对于任何大小的字典来说都会非常慢。你有没有考虑过使用哈希字典?即。

$dict = { word1 => 1, word2 => 1....... etc } # for example...

for my $word (@list) 
{ 
   if ($dict->{$word})
   {
      print "Matched\n";
   }
   else
   {
      print "Not matched\n";
   }
}

请注意,我不主张以这种方式创建哈希,这只是一个使用哈希作为字典显示的示例,其中键是单词,值是常量'true'值。如果匹配必须不区分大小写,则在将字典单词插入哈希之前将其小写,并在执行查找之前使用小写$ word。

编辑:这是一些代码,用于从每行一个单词的文件中加载字典

open(FH,'dictionary.txt');
$dict = { map {chomp; $_,1} <FH> }
close(FH)

说明:

  1. &LT; FH&GT;在列表上下文中读取 整个文件
  2. map函数评估块     (每条线上的东西)
  3. 该块删除换行符和     返回一个两元素列表     包含单词和'1'
  4. 整个返回的列表用于 初始化哈希
  5. 存储对哈希的引用 $字典

答案 1 :(得分:2)

我很喜欢

grep { $_ =~ /blah/} @foo

这让我比以后更容易修改条件

grep(/blah/, @foo)

但我没有看到你的语法有什么问题。

答案 2 :(得分:2)

不是编写自己的代码来比较@list的每个元素与@dict的每个元素,而是使用已经为你完成工作的模块,比如List::Compare

use strict;
use warnings;
use List::Compare;

my @dict = qw(apple banana orange grape pomegranate);
my @list = qw(banana giraffe pomegranate apple);

my $lc = List::Compare->new(\@dict, \@list);
my @intersection = $lc->get_intersection;

print "words found in the dictionary: " . join(', ', @intersection) . "\n";

答案 3 :(得分:2)

你的grep语法很好。

但是,我觉得有必要对你的算法发表评论。这很浪费。

@dict中的每个字进行一次@list次迭代。

将一个数组分配到哈希的键中并对哈希进行查找会更快:

my %lut;
@lut{@list} = ();

for my $word ( @dict ) {
    print exists $lut{$word} ? "Matched and Found\n" : "Not Matched\n";
}

哈希查找在恒定时间内发生,因此不是嵌套循环,而是有一个平坦的循环。随着你的单词列表增长,速度差异应该变得非常明显。

答案 4 :(得分:1)

我会使用List::Util::first。它会在第一个答案后停止处理列表。 grep不会这样做。

if( defined first { /$word/ } @list ) {
    print "Matched and Found\n";
}
else {
    print "Not Matched\n";
}

答案 5 :(得分:0)

这个很容易:没有错。 我可以在Perl中运行该代码,并按预期工作。 问题必定在其他地方。你使用“严格使用”;在文件的顶部?

答案 6 :(得分:0)

您的语法没有问题。它不是非常Perlish。事实上,你的代码说“你好,我有C背景!”。因此,首先,我会在grep之后摆脱parens。

但真正需要更多思考的是你的正则表达。如果@list包含'sex',但@dict包含'Essex',该怎么办?我将该正则表达式更改为:

m/^$word$/i

答案 7 :(得分:0)

在Perl 5.10中,我们有智能匹配!

foreach my $word (@list) {
  say $word ~~ @dict ? 'Matched and Found' : 'Not Matched';
}

答案 8 :(得分:0)

我对藏文字母一无所知。下面的例子假设你的字典包含单词后跟一个等号和每行上单词的定义。

它使用File::Slurp有效地将文件作为行列表,chomp的每一行,并将其拆分以将单词作为键,定义作为{{1}中的值哈希。

它假设%dict已经包含单个单词,而且不需要从@words这样的任意文本中识别单词(请参阅我的评论,指出单词在藏文中没有分开,只有音节是)。

要修改代码以从外部文件读取字典,请将"a.a.b.a.b.b.a.a.b.a"替换为文件名。

\*DATA

输出:

'a' means Letter 1
'b' means Letter 2
'a.b' means Letter 1 and Letter 2
'b.a' means Letter 2 and Letter 1
'a.a' not found
'b.a.b' means Letter 2 and Letter 1 and Letter 2

答案 9 :(得分:0)

  

您可以使用单词边界来匹配字词中的单词。 (除了页面的开头和结尾之外,一个单词被一个或多个空格包围)。

你可以使用这个

$dict ="squirrel in my pocket ";

@list =(squirrel,in,me,poc);

foreach my $word (@list)
{
  if(grep(/\b$word\b/, $dict))       
  {
    print "\$word:$word  Matched with     \$dict :$dict \n";
  }
  else
  {
   print "\$word:$word  Not Matched with \$dict :$dict \n";
  }
}

输出:

$word:squirrel  Matched     with  $dict :squirrel in my pocket
$word:in        Matched     with  $dict :squirrel in my pocket
$word:me        Not Matched with  $dict :squirrel in my pocket
$word:poc       Not Matched with  $dict :squirrel in my pocket