Skip to content

Perl 运算符

运算符是一个符号,它告诉编译器或解释器执行特定的数学、关系或逻辑运算并产生最终结果。例如,在表达式 4 + 5 中,4 和 5 是操作数(operand),+ 是运算符(operator)。

Perl 支持丰富的运算符集合。主要类别包括:

  • 算术运算符
  • 比较(关系)运算符
  • 逻辑运算符
  • 赋值运算符
  • 位运算符
  • 字符串运算符
  • 杂项运算符(包括引用符类运算符和箭头运算符)

让我们通过示例来探讨这些运算符。假设 my $a = 10; 和 my $b = 20; 用于数值示例,my $x = "hello"; my $y = "world"; 用于字符串示例。

这些运算符执行数学计算。

运算符描述示例(假设 $a=10, $b=20)
+加法:对两边的值相加。$a + $b 将得到 30
-减法:从左侧操作数中减去右侧操作数。$a - $b 将得到 -10
*乘法:对两边的值相乘。$a * $b 将得到 200
/除法:用左侧操作数除以右侧操作数。$b / $a 将得到 2
%取模:用左侧操作数除以右侧操作数,并返回余数。$b % $a 将得到 0
**幂运算:将左侧操作数提升到右侧操作数指定的幂次。$a**2 将得到 100 (10 的 2 次幂)

这些运算符比较两个操作数并返回一个布尔值(真或假)。Perl 为数值比较和字符串比较提供了不同的运算符集合。

运算符描述示例(假设 $a=10, $b=20)
==等于:如果数值相等则为真。($a == $b) 为假。
!=不等于:如果数值不相等则为真。($a != $b) 为真。
<=>数值比较:如果左侧小于右侧返回 -1,相等返回 0,左侧大于右侧返回 1。($a <=> $b) 返回 -1。
>大于:如果左侧操作数在数值上大于右侧则为真。($a > $b) 为假。
<小于:如果左侧操作数在数值上小于右侧则为真。($a < $b) 为真。
>=大于或等于:如果左侧操作数在数值上大于或等于右侧则为真。($a >= $b) 为假。
<=小于或等于:如果左侧操作数在数值上小于或等于右侧则为真。($a <= $b) 为真。

假设 my $s1 = "apple"; my $s2 = "banana";

运算符描述示例
lt小于:如果左侧参数在字符串比较上小于右侧则为真。($s1 lt $s2) 为真。
gt大于:如果左侧参数在字符串比较上大于右侧则为真。($s1 gt $s2) 为假。
le小于或等于:如果左侧参数在字符串比较上小于或等于右侧则为真。($s1 le $s2) 为真。
ge大于或等于:如果左侧参数在字符串比较上大于或等于右侧则为真。($s1 ge $s2) 为假。
eq等于:如果左侧参数在字符串比较上等于右侧则为真。($s1 eq $s2) 为假。
ne不等于:如果左侧参数在字符串比较上不等于右侧则为真。($s1 ne $s2) 为真。
cmp字符串比较:基于字典顺序比较(类似于数值的 <=>),返回 -1、0 或 1。($s1 cmp $s2) 返回 -1。

这些运算符为变量赋值。大多数可以与其他运算符结合使用以形成简写形式。

运算符描述示例(假设 $a=10)
=简单赋值:将右侧的值赋给左侧操作数。my $c = $a + $b; 将 30 赋给 $c。
+=加并赋值:将右侧操作数加到左侧,并将结果赋给左侧。$c = 5; $c += $a; ($c 变为 15,等同于 $c = $c + $a)。
-=减并赋值:从左侧减去右侧,并将结果赋给左侧。$c = 15; $c -= $a; ($c 变为 5,等同于 $c = $c - $a)。
*=乘并赋值:将左侧乘以右侧,并将结果赋给左侧。$c = 2; $c *= $a; ($c 变为 20,等同于 $c = $c * $a)。
/=除并赋值:将左侧除以右侧,并将结果赋给左侧。$c = 20; $c /= $a; ($c 变为 2,等同于 $c = $c / $a)。
%=取模并赋值:对左侧取模,并将结果赋给左侧。$c = 25; $c %= $a; ($c 变为 5,等同于 $c = $c % $a)。
**=幂并赋值:将左侧操作数提升到右侧指定的幂次,并将结果赋给左侧。$c = 2; $c **= 3; ($c 变为 8,等同于 $c = $c ** 3)。
.=字符串连接并赋值:将右侧字符串连接到左侧,并将结果赋给左侧。my $str = "Hi "; $str .= "Perl"; ($str 变为 “Hi Perl”)。
x=字符串重复并赋值:将左侧字符串重复右侧指定的次数,并将结果赋给左侧。my $str = "-"; $str x= 3; ($str 变为 ”---”)。

位运算符对数字的二进制表示进行操作。

假设 $a = 60;(二进制 00111100)和 $b = 13;(二进制 00001101)。

运算符描述示例
&按位与:如果某位在两个操作数中都存在,则将其复制到结果中。($a & $b) 得到 12(二进制 00001100)。
|按位或:如果某位在任一操作数中存在,则将其复制到结果中。($a | $b) 得到 61(二进制 00111101)。
^按位异或:如果某位仅在一个操作数中设置而非两个操作数都设置,则将其复制到结果中。($a ^ $b) 得到 49(二进制 00110001)。
~按位非(一的补码):一元运算符,翻转所有位。(采用二进制补码形式)。结果取决于系统的整数大小。(~$a) 得到 -61。
<<左移:将左侧操作数的位向左移动由右侧操作数指定的位数。用零填充空位。$a << 2 得到 240(二进制 11110000)。
>>右移:将左侧操作数的位向右移动。对于无符号数,用零填充空位。对于有符号数,行为可能有所不同(算术右移 vs. 逻辑右移)。$a >> 2 得到 15(二进制 00001111)。

逻辑运算符通常与布尔值或评估为真/假的表达式一起使用。

假设 $x 为真(例如,1),$y 为假(例如,0 或 undef)。

运算符描述示例
and逻辑与(低优先级):如果两个操作数都为真则为真。($x and $y) 为假。
&&逻辑与(高优先级,C 风格):如果两个操作数都为真则为真。支持短路评估。($x && $y) 为假。
or逻辑或(低优先级):如果至少一个操作数为真则为真。($x or $y) 为真。
||逻辑或(高优先级,C 风格):如果至少一个操作数为真则为真。支持短路评估。($x || $y) 为真。
not逻辑非(低优先级):反转操作数的逻辑状态。not $y 为真。
!逻辑非(高优先级,C 风格):反转逻辑状态。!$y 为真。
//已定义或(Perl 5.10 起):如果左侧操作数已定义则返回左侧,否则返回右侧。支持短路评估。my $val = undef; my $default = $val // "default_value"; ($default 变为 “default_value”)。

短路评估:&& 和 ||(以及 //)只在必要时评估其右侧操作数。例如,在 expr1 && expr2 中,如果 expr1 为假,则不会评估 expr2。

Perl 提供了灵活的方式来引用字符串和其他字面量。q{} 表示任意一对平衡的定界符(例如,q()、q<>、q##)。

运算符描述示例
q{ }单引号:仅对 \\ 和 \{定界符} 进行插值。q{don't interpolate $var} 结果为字面字符串 ‘don’t interpolate $var’。
qq{ }双引号:执行变量和转义序列插值。my $name = "Perl"; qq{Hello, $name!} 结果为 “Hello, Perl!”。
qx{ }命令执行(反引号):将内容作为系统命令执行并返回其标准输出。qx{ls -l} 或 `ls -l` 执行 ls -l。
qw{ }引用词语:按空白字符将内容分割成单引号引用的词语列表。qw{foo bar baz} 等同于 ('foo', 'bar', 'baz')。
qr{ }正则表达式引用:将内容编译为正则表达式并返回一个 regex 对象。my $regex = qr/pattern/i;
运算符描述示例
.字符串连接:连接两个字符串。"hello" . " " . "world" 得到 “hello world”。
x字符串重复:将左侧字符串操作数重复右侧操作数指定的次数。"-" x 3 得到 ”---”。
..范围运算符:在列表上下文(list context)中,创建从左到右递增的值列表。在标量上下文(scalar context)(例如,在 if 中)中,它是一个双稳态触发器运算符(flip-flop operator)。列表:(1..5) 得到 (1, 2, 3, 4, 5)。标量:if ($line_num .. $end_line_num) (flip-flop)。
++自增:将一个整数值增加一。可以是前缀形式(++$var)或后缀形式($var++)。my $i = 5; $i++; ($i 变为 6)。
—自减:将一个整数值减少一。可以是前缀形式(--$var)或后缀形式($var--)。my $i = 5; $i--; ($i 变为 4)。
->箭头运算符(中缀解引用):用于解引用,通常用于访问数组/哈希元素或调用对象的方法。$array_ref->[0]、$hash_ref->{key}、$object->method()。

运算符优先级决定了在包含多个运算符的表达式中执行操作的顺序。可以使用括号 () 来明确控制评估顺序。下面是从最高到最低优先级的一个简化列表。请参阅 perldoc perlop 获取完整、权威的列表。

1. 项和列表运算符(左联):`print`, `qw//` 等
2. 箭头运算符:`->`
3. 自增和自减:`++`, `--`(非联想)
4. 幂运算:`**`(右联想)
5. 一元运算符:`!`, `~`, `\`(引用),一元 `+`,一元 `-`(右联想)
6. 绑定运算符:`=~`, `!~`(左联想)
7. 乘法类:`*`, `/`, `%`, `x`(字符串重复)(左联想)
8. 加法类:`+`, `-`, `.`(字符串连接)(左联想)
9. 移位运算符:`<<`, `>>`(左联想)
10. 命名一元运算符:`stat`, `chomp` 等(非联想)
11. 关系运算符:`<`, `>`, `<=`, `>=`, `lt`, `gt`, `le`, `ge`(非联想)
12. 相等性运算符:`==`, `!=`, `<=>`, `eq`, `ne`, `cmp`(非联想)
13. 按位与:`&`(左联想)
14. 按位或和异或:`|`, `^`(左联想)
15. C 风格逻辑与:`&&`(左联想)
16. C 风格逻辑或:`||`(左联想)
17. 已定义或:`//`(左联想)
18. 范围运算符:`..`, `...`(非联想)
19. 条件(三元)运算符:`? :`(右联想)
20. 赋值运算符:`=`, `+=`, `-=`, `*=`, 等(右联想)
21. 逗号运算符,列表分隔符:`,`, `=>`(左联想)
22. 列表运算符(右联):`print`(如果在逗号右侧)等
23. 逻辑非(低优先级):`not`(右联想)
24. 逻辑与(低优先级):`and`(左联想)
25. 逻辑或和异或(低优先级):`or`, `xor`(左联想)

理解优先级对于编写正确且无歧义的 Perl 代码至关重要。拿不准时,请使用括号。