我有以下代码,尤其是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个点?
答案 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:/
的行”(即使它是相同的行)。