本文和大家重点讨论一下绑定Perl操作符和乘号Perl操作符,绑定Perl操作符中双目=~把一个字串和一个模式匹配、替换或者转换绑定在一起,并且Perl提供类似C的Perl操作符(乘)、/(除)、和%(模除)。
绑定Perl操作符
双目=~把一个字串和一个模式匹配、替换或者转换绑定在一起。要不然这些操作会搜索或修改包含在$_(缺省变量)里面的字串。你想绑定的字串放在左边,而Perl操作符本身放在右边。返回值标识右边的Perl操作符的成功或者失败,因为绑定Perl操作符本身实际上不做任何事情。
如果右边的参数是一个表达式而不是模式匹配、子过程或者转换,那运行时该表达式会被解释成一个搜索模式。也就是说,$_=~$pat等效于$_=~/$pat/。这样做要比明确搜索效率低,因为每次计算完表达式后都必须检查模式以及可能还要重新编译模式。你可以通过使用qr//(引起正则表达式)Perl操作符预编译最初的模式的方法来避免重新编译。
双目!~类似=~Perl操作符,只是返回值是=~的对应返回值的逻辑非。下面的表达式功能上是完全一样的:
$string!~/pattern/
not$string=~/pattern/
我们说返回值标识成功,但是有许多种成功。替换返回成功替换的数量,转换也一样。(实际上,转换Perl操作符常用于字符计数。)因为任何非零值都是真,所以所有的都对。最吸引人的真值类型是模式的列表赋值:在列表环境下,模式匹配可以返回和模式里圆括弧相匹配的子字串。不过,根据列表赋值的规则,如果有任何东西匹配并且赋了值,列表赋值本身将返回真,否则返回假。因此,有时候你会看到这样的东西:
if(($k,$v)=$string=~m/(\w+)=(\w*)/){
print"KEY$kVALUE$v\n";
}
让我们分解这个例子。=~的优先级比=高,因此首先计算=~。=~把字串$string绑定与右边的模式进行匹配,右边是扫描你的字串里看起来象KEY=VALUES这样的东西。这是在列表环境里,因为它是在一个列表赋值的右边。如果匹配了模式,它返回一个列表并赋值给$k和$v。列表赋值本身是在标量环境,所以它返回2--赋值语句右边的数值的个数。而2正好又是真——因为标量环境也是一个布尔环境。当匹配失败,没有赋值发生,则返回零,是假。
关于模式规则的更多内容,参阅第五章,模式匹配。
乘号Perl操作符
Perl提供类似C的Perl操作符(乘)、/(除)、和%(模除)。和/的运行和你预料的一样,对其两个操作数进行乘或除。除法是以浮点数进行的,除非你用了integer用法模块。
%Perl操作符在用整数除法计算余数前,把它的操作数转换为整数。(不过,如果必要,它会以浮点进行除法,这样你的操作数在大多数32位机器上最多可以有(以浮点)15位。)假设你的两个操作数叫$b和$a。如果$b是正数,那么$a%$b的结果是$a减去$b不大于$a的最大倍数(也就意味着结果总是在范围0..$b-1之间)。如果$b是负数,那么$a%$b的结果是$a减去$b不小于$a的最小倍数(意味着结果介于$b+1..0之间)。
当useinteger在范围里时,%直接给你由你的C编译器实现的模除Perl操作符。这个Perl操作符对负数定义得不是很好,但是执行得更快。
双目x是复制Perl操作符。实际上,它是两个Perl操作符,在标量环境里,它返回一个由左操作数重复右操作数的次数连接起来的字串。(为了向下兼容,如果左操作数没有位于圆括弧中,那么它在列表环境里也这样处理。)
print'-'x80;#打印一行划线
print"\t"x($tab/8),''x($tab%8);#跳过
在列表环境里,如果左操作数是在圆括弧中的列表,x的作用是一个列表复制器,而不是字串复制器。这个功能对初始化一个长度不定的数组的所有值为同一值时很有用:
@ones=(1)x80;#一个80个1的列表
@ones=(5)x@ones;#把所有元素设置为5
类似,你还可以用x初始化数组和散列片段:
@keys=qw(perlsbeforeswine);
@hash{@keys}=("")x@keys;
如果这些让你迷惑,注意@keys被同时当做一个列表在赋值左边使用和当做一个标量值(返回数组长度)在赋值语句右边。前面的例子在%hash上有相同的作用:
$hash{perls}="";
$hash{before}="";
$hash{swine}="";
【编辑推荐】