Perl设置计数器以匹配循环

时间:2017-07-29 14:14:30

标签: perl loops counter

除非是$counter++,否则如何将1设置为哈希?在这段代码中:

use strict;
    use warnings;    

    my @filestwo = glob("*.xml");
    my $result = @filestwo;          

    my $count = 0;
    my %justone;
    foreach my $domain (@filestwo) {
      open my $in, '<', $domain or die "Open fail on $domain $!\n";
        my @linestwo = <$in>;        

            for my $line (@linestwo) {

                if($line =~ /Domain:\s([a-z].+)/){
                  $count++;
                  print "Number:$count Your TLD $1!\n" unless $justone{$1}++;
                }                

            }

}

输出:

Number:1 Your TLD one.com!
Number:3 Your TLD three.com!
Number:5 Your TLD two.com!

应该是:

Number:1 Your TLD one.com!
Number:2 Your TLD three.com!
Number:3 Your TLD two.com!

关于代码的说明:

  • 打开3个文件.xml(在每个文件中都存在重复模式)
  • 创建哈希%justone;
  • 如果匹配模式,则从数组中搜索:domain
  • 如果匹配且在下一次迭代中再次匹配相同的模式,则只需使用unless $justone{$1}++;打印1

我的问题是,我不能仅为匹配关系设置一个计数器,除非哈希。

2 个答案:

答案 0 :(得分:1)

如果您只想增加,除非满足某些条件, 你应该在你的代码中提到它。

使用postfix foo() unless condition();语法意味着条件只会引用前面的语句,而不是整个范围(这可能是疯狂的解析)。

因此print '...' unless $foounless( $foo ){ print '...'; }相同。

因此,如果要在except条件中包含多个语句,则需要使用花括号:unless ( $foo ) { # as many lines as desired }

如果我理解你的问题,你想做:

unless ( $justone{$1}++ ){
    $count++;
    print "Number:$count Your TLD $1!\n"
}

仅在满足条件时才会增加,并导致所需的输出。我建议使用一个命名变量来获得你在$ 1中捕获的内容,以使其更具可读性。

答案 1 :(得分:1)

问题是$count++每个域应该只执行一次print,这意味着您只需将$count++移动到unless的正文中即可。< / p>

或者,您可以使用

简化代码
my %seen;
my @uniq_domains =
   grep !$seen{$_}++,
      map /Domain:\s([a-z].+)/,
         <$in>;

use List::Util qw( uniq );

my @uniq_domains =
   uniq
      map /Domain:\s([a-z].+)/,
         <$in>;

然后,以下输出您想要的内容:

say sprintf "%d. %s", $_+1, $uniq_domains[$_]
   for 0..$#uniq_domains;