Reputation: 377
I have the following code especially the condition in the if block and how the id is being fetched, to read the below text in the file and display the ids as mentioned below:
Using a Range operator ..:
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";
Text in the file
__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
Outputs:
90516 90517 90518
Question: Range operator is used with two dots why it is being used with 3 dots here??
Upvotes: 2
Views: 194
Reputation: 385764
First, its not really the range operator; it's known as the flip-flop operator when used in scalar context. And like all symbolic operators, it's documented in perlop.
...
is almost the same thing as ..
. When ...
is used instead of ..
, the end condition isn't tested on the same pass as the start condition.
$ 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'
Upvotes: 2
Reputation: 183301
Per http://perldoc.perl.org/perlop.html#Range-Operators:
If you don't want it to test the right operand until the next evaluation, as in sed, just use three dots ("...") instead of two. In all other regards, "..." behaves just like ".." does.
So, this:
/Work items:/ ... !/^\s*\(\d+\) (\d+)/
means "from a line that matches /Work items:/
until the next subsequent line that doesn't match /^\s*\(\d+\) (\d+)/
", whereas this:
/Work items:/ .. !/^\s*\(\d+\) (\d+)/
would mean "from a line that matches /Work items:/
until the line that doesn't match /^\s*\(\d+\) (\d+)/
" (even if it's the same one).
Upvotes: 0