Perl5学习笔记-第三章-操作符
2010-07-03 14:33:53 阿炯

一、算术操作符
二、数字比较操作符
三、字符串比较操作符
四、逻辑操作符
五、位操作符
六、赋值操作符
七、自增自减操作符
八、杂项运算符
九、逗号操作符
十、条件操作符
十一、其它常用的运算符
十二、操作符的次序
十三、操作符的一些说明


一、算术操作符 :+(加)、-(减)、*(乘)、/(除)、**(乘幂)、%(取余)、-(单目负)
(1)乘幂的基数不能为负,如 (-5) ** 2.5 # error;
(2)乘幂结果不能超出计算机表示的限制,如10 ** 999999 # error
(3)取余的操作数如不是整数,四舍五入成整数后运算;运算符右侧不能为零
(4)单目负可用于变量: - $y ; # 等效于 $y * -1
----------------------------------------------------
符号      示例      说明
+     $z=$x+$y     将$x和$y相加之后,再将结果指派给$z
-     $z=$x-$y     将$x减掉$y之后,再将结果指派给$z
*     $z=$x*$y     将$x和$y相乘之后,再将结果指派给$z
/     $z=$x/$y     将$x除以$y之后,再将商数指派给$z
%     $z=$x%$y     将$x除以$y之后,再将余数指派给$z
**     $z=$x**$y     将$x乘以$y之后,再将结果指派给$z
++     $x++;++$x;     如同$x=$x++1;将$x加一以后再将结果指派给$x
--     $x--;--$x;     如同$x=$x-1;将$x减一以后再将结果指派给$x

二、数字比较操作符
整数比较操作符
操作符    描述
<    小于
>    大于
==    等于
<=    小于等于
>=    大于等于
!=    不等于
<=>    比较操作符结果返回1,0, -1三者中的一个,解释如下:
0 - 两个值相等;1 - 第一个值大;-1 - 第二个值大
----------------------------------------------------
符号      示例      说明
>     $x>$y     如果$x大于$y,返回1的值,否则返回0
>=     $x>=$y     如果$x大于等于$y,返回1的值,否则返回0
<     $x<$y     如果$x小于$y,返回1的值,否则返回0
<=     $x<=$y     如果$x小于等于$y,返回1的值,否则返回0
==     $x==$y     如果$x等于$y,返回1的值,否则返回0
!=     $x!=$y     如果$x不等于$y,返回1的值,否则返回0
<=>    $x<=>$y     如果$x大于$y,返回1的值,如果$x等于$y,否则返回0;&127;如果 $x小于$y,则返回-1的值

三、字符串比较操作符
字符串比较操作符
操作符    描述
lt     小于
gt     大于
eq     等于
le     小于等于
ge     大于等于
ne     不等于
cmp     比较,返回 1, 0, or -1
----------------------------------------------------
符号      示例      说明
gt     $str1 gt $str2     如果$str1大于$str2,返回1的值,否则返回0
ge     $str1 ge $str2     如果$str1大于等于$str2,返回1的值,否则返回0
lt     $str1 lt $str2     如果$str1小于$str2,返回1的值,否则返回0
le     $str1 le $str2     如果$str1小于等于$str2,返回1的值,否则返回0
eq     $str1 ep $str2     如果$str1等于$str2,返回1的值,否则返回0
ne     $str1 ne $str2     如果$str1不等于$str2,返回1的值,否则返回0
cmp     $str1 cmp $str2     如果$str1大于$str2,返回1的值,如果$str1等于$str2,返回0,如果$str1小于$str2,则返回-1的值


Perl的比较操作符和Bash完全相反,数值比较采用符号,字符串比较采用字母。
数值     字符串      意义
-----------------------------
==       eq        相等
!=       ne        不等
<        lt        小于
>        gt        大于
<=       le        小于或等于
>=       ge        大于或等于
<=>      cmp       返回值-1/0/1

最后一个<=>和cmp用于比较两边的数值/字符串并返回状态码(-1/0/1):小于则返回-1,等于则返回0,大于则返回1。

对于<=>,如果比较的双方有一方不是数值,该操作符将返回undef。


四、逻辑操作符
逻辑或:$a || $b 或 $a or $b
逻辑与:$a && $b 或 $a and $b
逻辑非:! $a 或 not $a
逻辑异或:$a xor $b

Perl 逻辑运算符如下所示:
表格实例中我们设置变量 $a 为 true, $b 为 false。
运算符     描述     实例
and     逻辑与运算符符。如果两个操作数都为 true,则条件为 true。 ($a and $b) 为 false。
&&     C 风格的逻辑与运算符符。如果两个操作数都为 true,则条件为 true。($a && $b) 为 false。
or     逻辑或运算符。如果两个操作数中有任意一个非零,则条件为 true。($a or $b) 为 true。
||     C 风格逻辑或运算符。如果两个操作数中有任意一个非零,则条件为 true。($a || $b) 为 true。
not     逻辑非运算符。用来反转操作数的逻辑状态。如果条件为 true,则逻辑非运算符将使其为 false。not($a and $b) 为 true。

----------------------------------------------------
1、$x&&$y(and)
$x $y 结果
真(True) 真(True) 真(True)
真(True) 假(False) 真(True)
假(False) 真(True) 假(False)
假(False) 假(False) 假(False)

2、$x||$y(or)
$x $y 结果
真(True) 真(True) 真(True)
真(True) 假(False) 真(True)
假(False) 真(True) 真(True)
假(False) 假(False) 假(False)

3、!$x(not)
!$x 结果
真(True) 假(False)
假(False) 真(True)

五、位操作符
位与:&
位或:|
位非:~
位异或:^
左移:$x << 1
右移:$x >> 2
注:不要将&用于负整数,因为PERL将会把它们转化为无符号数。

Perl 支持的位运算符如下所示:
my ($a,$b)=(60,13);
运算符     描述     实例
&     如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。($a & $b) 将得到 12,二进制为 0000 1100
|     如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。($a | $b) 将得到 61 ,二进制为 0011 1101
^     如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。($a ^ $b) 将得到 49,二进制为 0011 0001
~     二进制反码运算符是一元运算符,具有"翻转"位效果,即0变成1,1变成0。(~$a ) 将得到 -61 ,二进制为 1100 0011 ,一个有符号二进制数的反码形式
<<     二进制左移运算符。左操作数的值向左移动右操作数指定的位数。$a << 2 将得到 240 ,二进制为 1111 0000
>>     二进制右移运算符。左操作数的值向右移动右操作数指定的位数。$a >> 2 将得到 15 ,二进制为 0000 1111


六、赋值操作符
操作符    描述
=    Assignment only
+=    Addition and assignment
-=    Subtraction and assignment
*=    Multiplication and assignment
/=    Division and assignment
%=    Remainder and assignment
**=    Exponentiation and assignment
&=    Bitwise AND and assignment
|=    Bitwise OR and assignment
^=    Bitwise XOR and assignment
Table 赋值操作符例子
表达式    等效表达式
$a = 1;     none (basic assignment)
$a -= 1;     $a = $a - 1;
$a *= 2;     $a = $a * 2;
$a /= 2;     $a = $a / 2;
$a %= 2;     $a = $a % 2;
$a **= 2;     $a = $a ** 2;
$a &= 2;     $a = $a & 2;
$a |= 2;     $a = $a | 2;
$a ^= 2;     $a = $a ^ 2;
=可在一个赋值语句中出现多次,如:
$value1 = $value2 = "a string";
=作为子表达式
($a = $b) += 3;
等价于
$a = $b;
$a += 3;
但建议不要使用这种方式。
----------------------------------------------------
符号      示例      说明
=     $x=$y;     将$x的值指派给$y

+=     $x+=$y;
$x=$x+$y;     将$x加$y之后再指派给$x

-=     $x-=$y;
$x=$x-$y;     将$x减$y之后再指派给$x

*=     $x*=$y;
$x=$x*$y;     将$x乘$y之后再指派给$x

/=     $x/=$y;
$x=$x/$y;     求出$x除以$y之后的商数,再指派给$x

**=     $x**=$y;
$x=$x**$y;     将$x乘上$y次方之后再指派给$x

%=     $x%=$y;
$x=$x%$y;     求出$x除以$y的余数以后,再指派给$x

.=     $str1.=$str2;
$str1=$str1.$str2;     将$str1这个字符串再加上$str2这个字符串之后,再指派给$str1这个字符串

x=     $strx=$y;
$str=$strx$y;     重复$str字符串$y次,并反结果指派给str这个字符串

七、自增自减操作符 :++、--(与C++中的用法相同)
不要在变量两边都使用此种操作符:++$var-- # error
不要在变量自增/减后在同一表达式中再次使用:$var2 = $var1 + ++$var1; # error
在PERL中++可用于字符串,但当结尾字符为'z'、'Z'、'9'时进位,如:
$stringvar = "abc";
$stringvar++; # $stringvar contains "abd" now
$stringvar = "aBC";
$stringvar++; # $stringvar contains "aBD" now
$stringvar = "abz";
$stringvar++; # $stringvar now contains "aca"
$stringvar = "AGZZZ";
$stringvar++; # $stringvar now contains "AHAAA"
$stringvar = "ab4";
$stringvar++; # $stringvar now contains "ab5"
$stringvar = "bc999";
$stringvar++; # $stringvar now contains "bd000"
不要使用--,PERL将先将字符串转换为数字再进行自减
$stringvar = "abc";
$stringvar--; # $stringvar = -1 now
如果字符串中含有非字母且非数字的字符,或数字位于字母中,则经过++运算前值转换为数字零,因此结果为1,如:
$stringvar = "ab*c";
$stringvar++;
$stringvar = "ab5c";
$stringvar++;

八、杂项运算符
引号运算符如下所示:
运算符     描述     实例
q{},为字符串添加单引号,q{abcd} 结果为 'abcd'
qq{},为字符串添加双引号,qq{abcd} 结果为 "abcd"
qx{},为字符串添加反引号,qx{abcd} 结果为 `abcd`

除了以上提到的运算符外还支持以下运算符:
运算符     描述     实例
.     点号 (.) 用于连接两个字符串。如果 $a="free", $b="oa" , $a.$b 结果为 "freeoa"
x     x 运算符返回字符串重复的次数。('-' x 3) 输出为 ---
..     .. 为范围运算符。(2..5) 输出结果为 (2, 3, 4, 5)
++     自增运算符,整数值增加 1。$a =10, $a++ 输出为 11
--     自减运算符,整数值减少 1。$a =10, $a-- 输出为 9
->     箭号用于指定一个类的方法。$obj->$a 表示对象 $obj 的 $a 方法

字符串联结和重复操作符,数字范围。
联接: .
重复:x
联接且赋值(类似+=): .=

=   assignment
.   string concatenation
x   string multiplication
..  range operator (creates a list of numbers)

$newstring = "potato" . "head";
$newstring = "t" x 5;
$a = "be";
$a .= "witched"; # $a is now "bewitched"


九、逗号操作符
其前面的表达式先进行运算,如:
$var1 += 1, $var2 = $var1;
等价于
$var1 += 1;
$var2 = $var1;
使用此操作符的唯一理由是提高程序的可读性,将关系密切的两个表达式结合在一起,如:
$val = 26;
$result = (++$val, $val + 5); # $result = 32
注意如果此处没有括号则意义不同:
$val = 26;
$result = ++$val, $val + 5; # $result = 27


细说逗号(列表)操作符
其中的参数是按照从左到右的次序被处理,跟上下文密切相关,当标量被用在一个隐含的列表中时,左边的参数被处理,然后就被忽略,并且返回右边的参数。
my $a=(1,3);

将把数值3传递给$a,在列表上下文中,所有的参数从左向右按列表的形式被返回。在不使用括号的情况下在标量上下文使用列表要小心,列表中的第一个元素比右边的元素更优先。
my $a=1,3;

则$a=1,因为它被解释为:
($a=1),3;

------------------
这跟C语言中对逗号的定义是一致的:
逗号运算符用于将多个表达式写在一起,从左到右依次运行每个表达式。

x = 10, y = 20;
上面有两个表达式(x = 10和y = 20),逗号使得它们可以放在同一条语句里面。

逗号运算符返回最后一个表达式的值,作为整个语句的值。

int x;
x = (1, 2, 3);

上面示例中,括号里面的逗号运算符,返回最后一个表达式的值,所以变量x等于3。
------------------

my ($a,$b)=(1,3,5);
my ($c)=(2,8);
say "a:$a,b:$b,c:$c";
>a:1,b:3,c:2

my ($a,$b)=(1,3,5);
my $c=(2,8);
say "a:$a,b:$b,c:$c";
>a:1,b:3,c:8

他人的两条总结:
## 1.标量上下文中的列表:得到最后一个元素
##   赋值语句返回标量左值
$a = (11,22);   # a=22,赋值语句返回22
$a = $b = (11,22); # a和b都等于22
# 下面func()最后返回空列表,标量上下文的赋值返回0,布尔假
while (($a, $b) = func()){}

# 赋值语句返回的标量左值可被修改
chomp ($str = "hello\n"); # 将会去除$str中的换行符
($a = $b) =~ s/xxx/yyy/;  # 将会修改变量a
($a += 2) *= 2; # 将会对a加2后乘2

## 2.列表上下文中的列表:逐个赋值
##   左边多的变量被赋值为undef,右边多的元素被丢弃
##   赋值语句本身的返回值:
##     在标量上下文:返回右边列表的长度
##     在列表上下文:返回左边列表
($a, $b) = (11,22);  # 赋值语句返回2或(11,22)
($a) = (11,22);      # 赋值语句返回2或(11)
() = (11,22);        # 赋值语句返回2或()
($a,$b,$c) = (11,22);  # 赋值语句返回2或(11,22,undef)
($a,undef,$c) = (11,22,33); # 赋值语句返回3或(11,undef,33)

$num = () = <>;     # 将已读取的行数赋值给num
$num = @arr = <>;   # 同上
@arr=($a,$b)=(11,22,33);  # @arr=(11,22),$a=11,$b=22


十、条件操作符/判别运算式
指令: 判别运算式?运算1:运算式2 条件运算符(Conditional Operator)

说明: 这个语法的意义和C语言一样,如果判别运算式的值是真(True)的话,则做运算 ,1的运算,如果判别运算式是假(False)的话,则做运算式2的运算,与C中类似,条件?值1:值2,当条件为真时取值1,为假时取值2,如:
$result = $var == 0 ? 14 : 7;
$result = 43 + ($divisor == 0 ? 0 : $dividend / $divisor);
PERL 5中,还可以在赋值式左边使用条件操作符来选择被赋值的变量,如:
$condvar == 43 ? $var1 : $var2 = 14;
$condvar == 43 ? $var1 = 14 : $var2 = 14;

示例:
$price=($age>60)? 100:200;
如果$age大于60的话,则$price等于100,否则$price等于200.

十一、其它常用的运算符
指令:..区块运算符(Range Operator)
说明:这个运算符是Perl语言中特有的运算符,是一个很实用的运算符.

示例:
@digits=(1..9); #此时@digits=(1,2,3,4,5,6,7,8,9);
@digits=('01'..'05'); #此时@digits=(01,02,03,04,05);
@char=('A'..'E'); #此时@char('A','B','C','D','E',);
@total=(1..3,'A'..'B'); #此时@total=(1,2,3'A','B');

十二、操作符的优先级与描述说明
下面列出了 Perl 语言的运算符优先级:
运算符符    结合性
++, --    无
-, ~, !    从右到左
**    从右到左
=~, !~    从左到右
*, /, %, x    从左到右
+, -, .    从左到右
<<, >>    从左到右
-e, -r,    无
<, <=, >, >=, lt, le, gt, ge    从左到右
==, !=, <=>, eq, ne, cmp    从左到右
&    从左到右
|, ^    从左到右
&&    从左到右
||    从左到右
..    从左到右
? and :    从右到左
=, +=, -=, *=,    从右到左
其他
,    从左到右
not    从左到右
and    从左到右
or, xor    从左到右


操作符    描述
++, --     自增,自减
-, ~, !     单目
**     乘方
=~, !~     模式匹配
*, /, %, x     乘,除,取余,重复
+, -, .     加,减,联接
    移位
-e, -r, etc.     文件状态
=, lt, le, gt, ge     不等比较
==, !=, , eq, ne, cmp     相等比较
&     位与
|, ^     位或,位异或
&&     逻辑与
||     逻辑或
..     列表范围
? and :     条件操作符
=, +=, -=, *=,     赋值
,    逗号操作符
not     Low-precedence logical NOT
and     Low-precedence logical AND
or, xor     Low-precedence logical OR and XOR   

操作符结合性(associativity):
操作符    结合性
++, --     无
-, ~, !     Right-to-left
**     Right-to-left
=~, !~     Left-to-right
*, /, %, x     Left-to-right
+, -, .     Left-to-right
    Left-to-right
-e, -r,     无
=, lt, le, gt, ge     Left-to-right
==, !=, , eq, ne, cmp     Left-to-right
&     Left-to-right
|, ^     Left-to-right
&&     Left-to-right
||     Left-to-right
..     Left-to-right
? and :     Right-to-left
=, +=, -=, *=,     Right-to-left
and so on     
,    Left-to-right
not     Left-to-right
and     Left-to-right
or, xor     Left-to-right
建议:
1、当你不确定某操作符是否先执行时,一定要用括号明确之。
2、用多行、空格等方式提高程序的可读性。

运算符     用法举例结果
int        int(5.6234)       返回它的参数的整数部分( 5)。
length     length("nose")    返回它的字符串参数的长度( 4)。
lc         lc("ME TOO")      返回它的转换成小写字母的参数(" me too ")
uc         uc("hal 9000")    返回与l c相反的参数值("HAL 9000")
cos        cos(5 0)        返回弧度5 0的余弦值( . 9 6 4 9 6 6)
rand       rand(5)         返回从0到小于该参数值之间的一个随机数字。如果该参数被省略,则返回0至1之间的一个数字

尖括号运算符
尖括号运算符<>,主要用于读写文件。
print "what size is your shoe?";
$size=<>;
print "your shoe size is $size, thank you!";

常用的文件数据(File test)运算符 示例 说明
-r $file 如果$file是可读取的话,返回1的值
-w $file 如果$file是可写入的话,返回1的值
-x $file 如果$file是可执行的话,返回1的值
-e $file 如果$file存在的话,返回1的值
-o $file 如果$file是被执行才所拥有的话,返回1的值
-s $file 返回$file的文件大小(bytes)
-f $file 如果$file是正常文件的话,返回1的值
-T $file 如果$file是文本文件的话,返回1的值
-B $file 如果$file是Binary文件的话,返回1的值
-M $file 返回$file文件最后一次更改时间到现在的日期数


十三、操作符的一些说明
一元运算符的不同函数,包括像ord和int的功能,以及所有的文件测试(-f-d)除了-t,其默认都是STDIN。
各种列表函数,如print和unlink。
模式匹配符m//, s///, 和 tr/// 当不使用 =~ 操作符。
如果没有其它变量提供,默认的迭代变量将在每次打循环。
隐式迭代变量在 grep 和 map函数。
把一个输入记录行输入操作的结果时,测试一段时间的测试(即)唯一标准本身的默认位置。需要注意的是一段测试外,不会出现这种情况。


该文章最后由 阿炯 于 2023-03-26 20:25:44 更新,目前是第 2 版。