在perl中使用Range运算符

时间:2014-11-14 18:36:05

标签: perl

我有以下代码,尤其是if块中的条件以及如何获取id,读取文件中的以下文本并显示如下所述的ID:

使用Range运算符..:

use strict;
use warnings;
use autodie;

#open my $fh, '<', 'sha.log';
my $fh = \*DATA;

my @work_items;

while (<$fh>) {
    if ( my $range = /Work items:/ ... !/^\s*\(\d+\) (\d+)/ ) {
        push @work_items, $1 if $range > 1 && $range !~ /E/;
    }
}

print "@work_items\n";

文件中的文字

__DATA__
Change sets:
  (0345) ---$User1 "test12"
    Component: (0465) "textfiles1"
    Modified: 14-Sep-2014 02:17 PM
    Changes:
      ---c- (0574) /<unresolved>/sha.txt
    Work items:
      (0466) 90516 "test defect
      (0467) 90517 "test defect
Change sets:
  (0345) ---$User1 "test12"
    Component: (0465) "textfiles1"
    Modified: 14-Sep-2014 02:17 PM
    Changes:
      ---c- (0574) /<unresolved>/sha.txt
    Work items:
      (0468) 90518 "test defect

输出:

90516 90517 90518

问题:范围运算符使用两个点,为什么它在这里用3个点?

2 个答案:

答案 0 :(得分:1)

首先,它不是范围运算符;它在标量上下文中使用时称为触发器操作符。和所有符号运算符一样,它记录在perlop

...几乎与..相同。如果使用...代替..,则不会在与开始条件相同的过程中测试结束条件。

$ perl -E'for(qw( a b a c a d a )) { say if $_ eq "a" .. $_ eq "a"; }'
a     # Start and stop at the first 'a'
a     # Start and stop at the second 'a'
a     # Start and stop at the third 'a'
a     # Start and stop at the fourth 'a'

$ perl -E'for(qw( a b a c a d a )) { say if $_ eq "a" ... $_ eq "a"; }'
a     # Start at the first 'a'
b
a     # Stop at the second 'a'
a     # Start at the third 'a'
d
a     # Stop at the fourth 'a'

答案 1 :(得分:0)

http://perldoc.perl.org/perlop.html#Range-Operators

  

如果您不希望它在下一次评估之前测试正确的操作数,就像在 sed 中一样,只需使用三个点(“...”)而不是两个点。在所有其他方面,“......”的行为就像“......”一样。

所以,这个:

/Work items:/ ... !/^\s*\(\d+\) (\d+)/

表示“从匹配/Work items:/的行到下一个与<{1}}不匹配的后续行,而这是:

/^\s*\(\d+\) (\d+)/

意味着“从匹配/Work items:/ .. !/^\s*\(\d+\) (\d+)/ 的行到不匹配/Work items:/的行”(即使它是相同的行)。