Perl 设置计数器以在循环中匹配

Perl set counter to match in loop

如何将 $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 !\n" unless $justone{}++;
                }                

            }

}

输出:

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!

代码说明:

我的问题,除非哈希,否则我不能只为匹配关系设置计数器。

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

使用后缀 foo() unless condition(); 语法意味着条件将只引用前面的语句,而不是整个范围(可以说解析起来很疯狂)。

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

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

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

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

只有在满足条件时才会递增,并导致所需的输出。不过,我建议为您在 $1 中捕获的内容使用命名变量,以使其更具可读性。

问题是 $count++ 应该像 print 一样每个域只执行一次,这意味着您可以简单地将 $count++ 移动到 unless 的正文中.

或者,您可以使用

简化代码
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;