我们说我有一个名为text.txt的文件,其中包含此
one
two
three
four
five
如果我在perl脚本中有这个
open($fh, '<', text.txt) or die "blah blah";
while(<$fh>){
print if 2..4;
}
它将打印两个,三个和四个。那个if语句如何在背景中将$ _与范围2..4进行比较?换句话说,如果我使用一个不同的变量,比如$ line而不是$ _,如果进行比较,我还需要写什么?
while(my $line = <$fh>){
print if........... 2..4 ?????????
}
谢谢。我喜欢Perl,但有一些事情我无法理解它是如何在后台完成的。
答案 0 :(得分:4)
范围运算符和$.
内置变量之间存在一定的魔力,后面的句子来自perlop(强调我的):
如果标量
".."
的操作数是常量表达式,那么 如果操作数与当前输入相等(==
),则认为该操作数为真 行号($.
变量)。
基本上,$.
是一系列处理过的行(从1开始),与范围进行比较。您可以使用命名变量获得相同的结果,简单如下:
while (my $line = <$fh>) {
print $line if 2..4;
}
或者如果您更喜欢撰写完整的if语句,则有一种等价形式:
while (my $line = <$fh>) {
if (2..4) {
print $line;
}
}
完整的,独立的解决方案可以写成:
#!/usr/bin/env perl
use strict;
use warnings;
while (my $line = <DATA>) {
print $line if 2..4;
}
__DATA__
one
two
three
four
five
产生输出:
two
three
four
答案 1 :(得分:3)
在标量上下文中,
".."
返回一个布尔值。运算符是双稳态的,如触发器,并模拟 sed , awk 和各种编辑器的行范围(逗号)运算符。每个".."
运算符都维护自己的布尔状态,甚至在调用包含它的子例程时也是如此。只要其左操作数为假,它就是假的。一旦左操作数为真,范围运算符将保持为真,直到右操作数为真, AFTER ,范围运算符再次变为假。在下一次评估范围运算符之前,它不会变为假。它可以测试正确的操作数,并在相同的评估中变为假(如 awk ),但它仍然返回true一次。如果您不希望它在下一次评估之前测试正确的操作数,就像在 sed 中一样,只需使用三个点("..."
)而不是两个点。在所有其他方面,"..."
的行为与".."
的行为相同。
例如,
for my $i (1,2,3,4,5,6,7,8,7,6,5,4,3,2,1) {
printf("%d: %s\n",
$i,
($i == 4) .. ($i == 6 || $i == 2) ? 'true' : 'false',
);
}
输出:
1: false
2: false
3: false
4: true
5: true
6: true
7: false
8: false
7: false
6: false
5: false
4: true
3: true
2: true
1: false
($i == 4)
是操作员开始返回true的时候。($i == 6 || $i == 2)
是操作员停止返回true的时候。if 2..4
是
的缩写if ($. == 2) .. ($. == 4)
是
的缩写if !$in
? do { $in = 1 if ($. == 2); $in }
: do { $in = 0 if ($. == 4); 1 }
由于$.
通常会单调增加,因此它等同于
if $. >= 2 && $. <= 4