使用正则表达式从perl中提取单词

时间:2013-07-22 04:38:06

标签: regex perl

我有这个文件:

1. heavenns 2 heavenns 3 heavenns good 4 heavenns 5heavennly bye

从这一行开始,只应打印一次'heavenns''heavennly'

我这个代码是我在其他帖子中提出的另一个问题。我想我已经在那里接受了我的问题,现在没有人会看到它,对吧? (我是新来的,我不知道它是如何工作的?)

#!/usr/bin/env perl
use strict;
use warnings;

my $regex = "heavenn+";
my $rx = qr/$regex/;
print "Regex: $regex\n";

my $file  = "myfilename.txt";
my %list;
my @myarr;
open my $fh, "<", $file or die "Failed to open $file: $?";

while ( my $line = <$fh> ) {
    if ($line =~ $rx)
    {
        print $line;
        $list{$line}++;
    }
 }

 push @myarr, sort keys %list;

 print "Mylist: @myarr\n"; #NOT GIVING ME UNIQUE VALUES & NOW I ONLY WANT heavenns and heavennly

4 个答案:

答案 0 :(得分:1)

perl -0777 -nE'@w{m/(heavenn\w+)/g}=();say for keys %w'

答案 1 :(得分:0)

您没有正确使用哈希。

  1. 检查哈希中是否存在单词。
  2. 如果不存在,请输入。如果是,请跳过。
  3. 循环后,打印出哈希内容。 无需使用数组。

答案 2 :(得分:0)

当你想要的只是打印出匹配的单词时,你打印出整行。如果是这种情况,那么您需要做的第一件事就是更改正则表达式:

my $rx = qr/heavenn.*?\b/

这匹配“heavenn”加上任何字符直到下一个单词边界。很难从你的问题中判断出这是否是你需要的正确的正则表达式,但它会与“天堂”和“天堂”相匹配,所以我坚持这一点。如果这不是您想要的,您可能需要稍微改变一下以满足您的需求。

接下来,只需稍微更改while循环,将匹配的单词提取到哈希中。你可以这样做:

while (my $line = <$fh>) {
    $list{$_}++ for $line =~ /$rx/g;
}

say for sort keys %list;   #Need to 'use feature qw(say);'
# => prints "heavennly\heavenns\n"

答案 3 :(得分:0)

在列表上下文中使用正则表达式时,您将获得所有匹配项。你遇到的另一个问题是正则表达式本身。当您使用+时,表示将使用加号前面的单词。你需要一个野猫。这是.。所以你的正则表达式必须像heavenn.。例如你的问题:

my $regex = "heavenn.";

my $file = "myfilename.txt";
my %list;
my @myarr;

#open my $fh, "<", $file or die "Failed to open $file: $?";

while ( my $line = <DATA> ) {
  my @founds = $line =~ m/$regex/g;
  foreach my $found ( @founds ) {
    print $found . "\n";
    $list{$found}++;
  }
}

push @myarr, sort keys %list;

print "Mylist: @myarr\n";

__DATA__

1. heavenns 2 heavenns 3 heavenns good 4 heavenns 5heavennly bye

我在这里使用这种方式将所有匹配作为一个数组并循环遍历找到的结果,只找到1个唯一的匹配(就像你一样)。