入门篇包括但不限于以下内容
注:尽管本文中没有提及逻辑控制符,但Perl的逻辑控制符与C 或者 JAVA 的逻辑控制符号 基本一致, 都支持与或非的操作 也就是 ! | & 这几个符号,使用上也没有太大差异。因而本文中就此略过,如有需要请自行查阅相关文档
Unix系统自带Perl,被称为“Unix工具箱”
被称为“实用摘录与报表语言” Practical Extraction and Report Language
也被称为“病态这种式垃圾列表器” Pathologically Eclectic Rubbish Lister
Perl 座右铭: There’s More Than One Way To Do It !
Perl擅长于文本处理和系统管理,不适合于实时嵌入式系统编程、操作系统底层开发(比如驱动程序开发)、复杂的多线性共享内存应用以及极度大的应用。
Perl的发明历史
Perl的特点
一些特点的记忆增强
尝试用一句话描述Perl
尝试用一个词描述Perl
没有查阅到相关资料,后续补充
Comprehensive Perl Archive Network
Perl综合典藏网 ( http://search.cpan.org/ )
perl 的模块扩展,用于下载基于perl的各种扩展模块及文档资料等。
CPAN也需要额外安装
yum install -y perl-CPAN
cpan的使用同数据库类似,需要进入相应的操作界面, 使用 perl -MCPAN -e shell 进入该操作界面
具体的模块和安装命令后续会聊到。
https://www.perl.org/get.html 登录官网下载对应版本安装,打印版本验证安装
perl -v
学习过 shell 脚本语言的程序员将会在perl的学习上有所助益。
Perl是一个纯文本文件,可以用任意的文本编辑器来编写Perl程序,例如txt,vm/vim,notepad等
mkdir -p /data/test/
vim /data/test/HelloWorld.pl
键入
#!/usr/bin/perl
print "Hello world!\n";
保存后使用 perl 运行这个文件 。
注:如果使用非管理员用户,请注意当前用户是否有执行权限
perl /data/test/HelloWorld.pl
你可以看到程序会输出相应的字符
继续阅读的一些补充知识点 -> 给刚接触脚本语言的同僚
Perl 的 use 关键字,你在本文的剩余部分会频繁地看到 use 5.014; use warings; use utf8; use strict 等代码,use 关键字实际上是对Perl 程序模块的装载,这是Perl可插拔式编程的关键用法。
上述代码中例如 use 5.014 表示使用 Perl 5 版本号 14 的支持,say 函数在该版本才能够正常使用。
关于use 关键字,还有很多可以展开的,但是现在你只需要记住它被用于引入Perl 程序的模块支持。
关于Perl use 关键字,这里提供一些参考文档:
http://blog.chinaunix.net/uid-608135-id-4439772.html 这里解释了 use 关键字的底层实现和它的用法
http://bbs.eetop.cn/thread-613055-1-1.html 这里提到了 use 关键字 和 require 关键字的执行阶段不同
#!/usr/bin/perl , 你会注意到每一个Perl程序头部的这行字。如果你不熟悉Linux 和脚本语言,也许会对它感到困惑。这是 脚本语言 在 Linux操作系统中的规约,用于告诉操作系统,执行该文件时调用何种解释器。你可以在上面的编写的第一个程序中看到这个区别
这个调用过程指的是 直接运行该脚本文件时,例如
./test.pl
没有任何前缀指向当前文件夹下的test.pl 脚本,操作系统会从第一行声明的解释器路径取查找解释器,用该解释器执行这个脚本。(使用这种方式需要给文件赋予权限)
如果指令编程
perl ./test.pl
显式地声明了执行脚本的解释器,那么头部行没有写也可以。(使用这种方式可以绕过权限限制)
包括以下内容
Perl内部不存在整数值,所有数字都将被存储为“双精度浮点数”(gcc编译的double类型),
可以直接用整数表示。例如:5 --> 解释为 5.00
注:Perl 内部会使用整数,但编程人员无需关心,其次Perl可以使用integer编译命令编译整数。
Perl 允许在整数中间插入 下划线 _ , 例如表示一个银行卡, 6217_0013_0000_0992_328, 这样看起来就很清楚(如不需要计算,此类数据建议使用字符串表示)
Perl支持加减乘除和模运算以及幂运算等
数字运算操作 | 操作符 | 示例 | 示例操作结果 |
---|---|---|---|
加法 | + | 2 + 3 | 5.00 |
减法 | - | 5.1 - 2.4 | 7.50 |
乘法 | * | 1 * 2 | 2.00 |
除法 | / | 14 / 7 | 2.00 |
模运算 | % | 5 % 2 | 1.00 |
幂运算 | ** | 2 ** 3 | 8.00 |
数字比较操作 | 操作符 | 示例 | 示例操作结果 |
---|---|---|---|
相等 | == | 1 == 1 | 真 |
不等 | != | 1 != 1 | 假 |
小于 | < | 1 < 1 | 假 |
大于 | > | 1 > 1 | 假 |
小于或等于 | <= | 1 <= 1 | 真 |
大于或等于 | >= | 1 >= 1 | 真 |
关于真假的布尔定义,稍后的章节会说明
Perl 的字符串是被单引号’’ 或 双引号 “” 包围的文本,例如: ‘a character’, “still character”;
Perl 的字符串长度无限制。(体现了Perl 原则之一:无内存限制) 0 - Memory-Max
Perl 字符完全支持 Unicode。(需要声明编码格式)
use charset 函数,声明文件的编码格式
encoding(charset) 函数,指定特定行为的编码格式
单引号 ’ ’
双引号 " "
#!/usr/bin/perl
use 5.014;
# 单引号中转义符只能用于转义反斜线本身和单引号
print '\n只是\n';
print "\n";
print '输出一个单引号 \',在输出一个反斜线\\';
print "\n";
# 双引号中转义符\有效,且能够使用$内插一个变量到字符串中
my $sum = 5 + 3;
print "5 + 3 = $sum \n";
print "\uhello \uworld! \n";
. 点可以作为字符串的连接操作符,如下
#!/usr/bin/perl
print "hello " . 'world' . "/n"; # 输出 hello world [换行符]
x 操作符可以重复输出相同的字符,如下
重复次数在使用前会先取整,去掉小数位,重复次数小于等于0时,生成空字符串
#!/usr/bin/perl
print "perl " x 3; #输出 perl perl perl
print "perl " x 2.8; #输出 perl perl
print "perl " x 0; #输出 [空字符串]
两者可以结合使用, 例如
#!/usr/bin/perl
print "perl " x 3 . "\n"; #输出 perl perl perl [换行符]
同样支持六种比较操作,但符号与数字不相同。
字符比较操作 | 操作符 | 示例 | 示例操作结果 |
---|---|---|---|
相等 | eq | “a” eq “a” | 真 |
不等 | ne | “35” ne “35.0” | 真,按照字符比较 |
小于 | lt | “b” lt “a” | 真, 按照字母顺序表 |
大于 | gt | “aa” gt “a” | 真, 按照字符长度 |
小于或等于 | le | “aa” le “aa” | 真 |
大于或等于 | ge | “aa” ge “aa” | 真 |
index 查找子字符串
基本格式: index($STRING, matchString, [start_index])
查找指定字符串在目标字符串中的相对位置,返回匹配到的下标值, 未匹配到则返回 -1
#!/usr/bin/perl
my $stuff = "hello world";
my $where = index $stuff, "world"; # $where = 6
my $where1 = index $stuff, "l"; # $where1 = 2
my $where2 = index $stuff, "l", $where1 + 1; # $where2 = 3
my $where3 = index $stuff, "l", $where2 + 1; # $where3 = 9
my $where4 = index $stuff, "l", $where3 + 1; # $where4 = -1
substr 截取字符串
基本格式: substr($STRING, start_index, [sub_length])
目标字符串被截取后并不会有任何变化
#!/usr/bin/perl
use 5.010;
my $str = "I solemnly swear that I am up to no good"
my $ret1 = substr $str, 20; # $ret1 = I am up to no good
say $ret1 . "\n" . $str; # $str还是等于原文
my $ret2 = substr $str, -4, 4; # $ret2 = good
say $ret2 . "\n" . $str; # $str还是等于原文
printf 和 sprintf格式化字符串
基本格式:printf(pattern, $String…)
基本格式:sprintf(pattern, $String…)
printf 与 sprintf有相同的参数和句柄,printf将直接把字符经过格式化后打印到命令行,而sprintf将返回格式化后的字符而不进行打印
printf 同java的格式化输出和C的格式化输出基本是一致的。
#!/usr/bin/perl
# %g 表示按需要自动选择浮点数、整数或者指数形式
# 2.5 3 1.0683e+29
printf "%g %g %g\n", 5/2, 51/17, 51**17;
# %d 表示十进制整数格式,将自动去掉小数点后的数字
# 2
printf "%d\n", 2.5;
# %6d 6表示定长字符,在输出日志等消息时频繁使用
# ······2 (·表示空格)
printf "%6d\n", 2;
运算操作符决定数字与字符串的结合产物,使用数字操作符连接则所有被连接的变量作为数字,使用字符操作符连接则被连接的变量被视为字符,如下所示
#!/usr/bin/perl
use 5.014;
say "1" + 2; #输出3
say "1" . 2; #输出12
say "1" x 3 + 2; #输出113 重复字符次数先运行
say "1" . 3 + 2; #输出15 加法先运行
say "1" x 3 * 2; #输出222 重复字符次数先运行
say "1" . 3 * 2; #输出16 乘法先运行
注:
操作符优先级,参考文档,常用的如右侧所示: () 高于 ++ – 高于 * / % x 高于 + - .
字符自动转换数字规则,首字符如果不为数字,则视为0,反之则取数字,直到匹配到不为数字的字符。如:
12kjsdha2321 会被视为 数字 12。
lksjdlak123 会被视为 数字 0。
代码演示
#!/usr/bin/perl use 5.014; say "ksjdhalkd23" * 12; # 输出 0 say "12ioqwnk3354" * 2; # 输出24
Perl 没有明确的两个标量值来定义真假
关于真假的定义是以假来定义的,下面这些都是假的值,除此之外,其他值都为真值
如下示例
#!/usr/bin/perl
use 5.014;
# 0为假
if(!0) {
say "hello";
}
# 空字符为假
if(!"") {
say "world";
}
# 任何非空的字符都为真
if('asdjkhasdk') {
say "anyway";
}
# 任何非0的数字都为真
if(5646545) {
say "everything is ok";
}
# undef 是假
if(undef == 0) {
say "undefined == false "
}
指存储值的容器,同其他编程语言的变量。
使用 $ 声明一个变量
命名区分大小写,字母或下划线_开头,可以由大小写字母,数字,下划线构成。
#!/usr/bin/perl
$variable1 = 1; #声明一个数字变量
$usr_variable = 1; #使用下划线连接多个单词的变量
$usrVariable = 1; #使用驼峰命名法
$USER_VARIBALE_CONSTANT = 1; #!!!不建议使用全大写的,可能与Perl保留的特殊变量名称冲突
使用 = 号连接 变量 和 标量完成赋值
#!/usr/bin/perl
$variable = "value";
字符变量和数字变量的操作符与标量相同,此外还支持双目赋值操作符
如下所示
#!/usr/bin/perl
use 5.014;
# 加等于操作
my $num1;
$num1 = $num1 + 1;
$num1 += 1;
say $num1;
# 输出2 0 + 1 + 1 = 2
# 减等于操作
my $num2;
$num2 = $num2 - 1;
$num2 -= 1;
say $num2;
# 输出 -2 0 - 1 - 1 = -2
# 乘等于操作
my $num3 = 1;
$num3 = $num3 * 2;
$num3 *= 2;
say $num3;
# 输出4 1 * 2 * 2 = 4
# 除等于操作
my $num4 = 1;
$num4 = $num4 / 2;
$num4 /= 2;
say $num4;
# 输出0.25 1 / 2 / 2 = 0.25;
# .等于操作(连接字符)
my $str1 = "one_";
$str1 = $str1 . "two_";
$str1 .= "three";
say $str1;
# 输出 one_two_three;
# x等于操作(字符串的重复次数操作)
my $str2 = "yo ";
$str2 = $str2 x 2;
$str2 x= 2;
say $str2;
# 输出 yo yo yo yo;
转载自 https://blog.csdn.net/henjay724/article/details/8457556#
考虑到示例不能完全体现关键字的主要作用和区别,对转载的内容中示例部分做了修改
由于原文有部分内容错误,这里也做出了修改。例如local不能声明一个新的变量,这里经过实验是可以,因而删除。此外还添加了部分内容以补充。
知识点概要:
变量范围分为两类:全局、局部
全局变量标准(our)关键字、局部私有变量(my)关键字
局部本地变量(local)关键字、持久性私有变量(state)关键字
在Perl中,所有的变量、子程序和其他可以被命名的实体默认都拥有包作用域(亦称“全局作用域”),也就是说它们存在于当前包的符号表中。可以在脚本文件中通过package 函数声明包名
package myPack;
如果不声明包名,则默认为main包。
如果没有关键字声明变量,Perl会默认变量为全局变量,但如果启用了 use strict 指令强制规定,则Perl会强制要求必须先声明变量后才可使用变量。
our操作符用于显式地创建包作用域变量。
#!/usr/bin/perl
use 5.010;
# 关键字our
sub subroutine1{
say $var; #得到全局的var变量
$var +=1;
say $var;
&subroutine2;
}
sub subroutine2{
$var +=1; #得到全局的var变量
say $var;
}
our $var =1; #全局, 作用域为包
&subroutine1; #输出1\n 2\n 3\n
say $var; #输出3\n
注1:our操作符是在Perl 5时代被引入的,Perl 4时代变量均为全局,且不需声明。到了Perl 5时代为避免变量混乱,引入了use strict指令强制规定必须声明变量,而our操作符就是定义了一个看起来像词法作用域的全局变量,从而通过strict指令限制。
注 2 :如果全局变量已存在,则 our 的作用是声明这个全局变量(类似于 C 中的 extern )。
local 修饰一个变量使其作为一个局部变量在该子程序域内有效,且与my不同,其可以继续传递到该子程序内部调用的其他子程序内,产生一个传递的效果。
#!/usr/bin/perl
use 5.010;
# 关键字local
sub subroutine0{
my $var = 100; #声明局部var变量,此时打印将得到局部变量
say $var;
&subroutine1;
}
sub subroutine1{
say $var; #my变量作为私有变量不能传递到其调用的子程序内,此时得到全局变量
local $var = 5; #临时全局变量, 作用域为子程序内部
say $var;
&subroutine2;
}
sub subroutine2{
$var +=1; #local变量将继续传递到其调用的子程序内部
say $var;
}
our $var =1; #全局, 作用域为包
&subroutine0; #输出100\n 1\n 5\n 6\n
say $var; #输出1\n
注 1 : local 变量是在运行时起作用,它会将参数的值保存在一个运行栈中,当执行线程离开所在作用域时,原先作用域暂存的变量会被恢复。
注2 : local和my都只在一个限定的代码块内生效,但是local的变量可以继续在这个代码块中调用的子程序中存在。
虽然local操作符的历史比my操作符久远,但Perl后来还是新增了my来分担local的工作,在大部分情况下应首选my,但也有一些特殊情况下必须使用local。
my操作符用于创建词法作用域变量,通过my创建的变量,存活于声明开始的地方,直到闭合作用域的结尾。
闭合作用域指的可以是一对花括号中的区域,可以是一个文件,也可以是一个eval字符串。
#!/usr/bin/perl
use 5.010;
# 关键字my
our $var =1; #全局变量,作用域为包
sub subroutine0{
my $var =2; #私有局部变量, 作用域为花括号
$var +=1;
say $var;
&subroutine1;
}
sub subroutine1{
say $var; #my私有变量不能传递到其调用的子程序内,仍然读取到全局变量
}
&subroutine0; #输出3\n 1\n
say $var; #输出1\n
注1:my是编译时在私有符号表中创建新变量,这个变量在运行时无法使用名字进行独立访问,即它不存在于包符号表中(非全局)。
注 2 :当闭合作用域里的 my 变量与外层变量重名时,当前 my 变量有效,当退出作用域时,外层变量值不变。
使用state操作符来声明变量,可以在子程序的多次调用期间保留变量之前的值,并将变量的作用域局限于子程序内部。
#!/usr/bin/perl
use 5.010;
# 关键字state
sub subroutine0 {
state $var =2; #持久局部变量, 作用域为子程序内部
$var += 1;
say $var;
&subroutine1;
}
sub subroutine1 {
say $var; #由于state变量和my变量都无法传递,因而这里输出空字符串
}
my $var = 1; #局部变量,作用域当前脚本文件
&subroutine0; #输出3\n 空字符串\n
&subroutine0; #输出4\n 空字符串\n
#这里输出4说明state在其作用域内上次操作的值得以保存
say $var; #输出1\n
注1:state 修饰的变量在退出子程序后将失效,要理解多次调用期间保留变量之前的值的含义是局限在作用域内的。
注2:state是从Perl 5.10开始引入的,所以使用前必须加上use 5.010或更高版本指令。
注 3 : state 可以声明标量、数组、哈希。但在声明数组和哈希时,不能对其初始化(至少 Perl 5.14 不支持)。
数组指存储列表的变量,每一个数组都包含一个列表。
基本格式: arrays[0] = 1; $element = arrays[0]; $element = arrays[-1];
如何声明一个数组 $NAME[index] = value
概要
数组下标指向一个标量即完成声明
下标为0的元素为数组的第一个元素
若声明的数组下标指向一个大于0的数,则自动扩充其和第一个元素之间的所有元素,扩充的元素默认为undef
#!/usr/bin/perl
$arr1[0] = 1; #声明一个数组arr1,并对其第一个元素赋值
$arr1[1.564] = 2; #自动去除小数点 等效于 $arr1[1] = 2;
$arr222[99] = 100;#声明一个数组arr222,并对其第100个元素赋值,其余99个元素值都为undef
如何获取数组的元素 N A M E [ i n d e x ] ∗ ∗ 或 者 ∗ ∗ NAME[index]** 或者 ** NAME[index]∗∗或者∗∗NAME[index的负数]
概要
- $数组下标获得一个数组元素
- 如果该数组下标不存在,返回一个undef
- 可以以负数为下标取值,即下标倒数,从-1开始
#!/usr/bin/perl
use 5.010;
$arr[0] = 'a';
$arr[1] = undef;
$arr[2] = "b";
my $value = $arr[0]; #获得数组的第一个元素 'a'
my $value = $arr[999999]; #如果超过数组下标最大长度,不会导致错误,只是得到一个undef值
my $value = $arr[$#arr];#获得数组最后一个元素 "b"
my $value = $arr[-1]; #获得数组最后一个元素 "b"
my $value = $arr[-2]; #获得数组倒数第二个元素 undef
my $value = $arr[-3]; #获得数组倒数第三个元素也就是第一个元素 'a'
my $value = $arr[-4]; #超过了数组的下标,得到undef值
如何获取数组的长度
概要
- $#ARRAYS_NAME(数组最后一个元素下标) + 1
#!/usr/bin/perl
$arr[9] = 10;
my $len = $#arr + 1; # $#arr = 9, 9 + 1 等于 10;
$arr[$#arr] = 10; # 因此可以通过这种形式修改获得得到数组的最后一个值,但是要在数组被声明的前提下,否则将导致错误
列表,列表在程序中表示一列数据。其与数组的关系如同比 值与变量的关系 一样,一个作为数据,一个作为存储数据的容器或者说引用。
如何表示一个列表?
#!/usr/bin/perl
(1, 2, 3) # 包含三个数字元素的列表
(1.25, "str") # 包含两个元素的列表
($var1, $var2) # 列表中也可以存储变量
(1..100) # 列表中可以使用.. 链接数字,其表示包含 1 - 100 的一百个数字
qw(windows linux ubuntu) #quoted world简写,等效于('windows', 'linxu', 'ubuntu'), 是快速声明字符列表的一种简写方式,注意其声明的是单引号的字符,因而不支持字符的转义
qw|(ios) (andorid) (harmonyOS)| #另外一个qw简写写法,qw简写可以使用不同的符号作为分界符,具体原因如该例中的写法,由于文本本身有括号,再使用括号就无法正确分界。该例等效于('(ios)', '(andorid)', '(harmonyOS)')
qw<1 2 3> #qw简写中,定界符也可以使用其他明确定义的左右符号,例如{}<>()[]。该例等效于('1','2','3')
列表如何赋值到变量\数组中?
@数组名 , 将表示整个数组,如下,假设该数组只有下标 0 - 2 三个元素
for e l e m e n t ( element ( element(arr[0], $arr[1], $arr[2]) {} 等效于 for $element (@arr) {}
#!/usr/bin/perl
($var1, $var2, $var3) = (1, 2, 3, 4, 5); # 列表可以直接赋值到变量中,相当于分别给三个变量赋值,多余的元素会被忽略,如果参数不足,则赋予undef值
($var1, $var2) = ($var2, $var1); # perl中快速交换两个变量值的方法
($arr[0],$arr[1],$arr[2]) = qw[狮子 斑鬣狗 花豹 野犬 猎豹 胡狼]; # 给数组下标 0 - 2 的元素赋值,多余的两个字符会被忽略
@arr = ('狮子', '斑鬣狗', '花豹', '野犬', '猎豹', '胡狼'); # 将列表中的元素赋值到数组中,从下标0开始
@arr = qw[狮子 斑鬣狗 花豹 野犬 猎豹 胡狼]; # 将列表中的元素赋值到数组中,从下标0开始, 这里比较上述两例,可以看到qw简写和@符号的使用
@copy = @arr; # 复制一个数组
栈 pop push操作
Perl的数组支持栈Stack 的操作,关于栈结构,可以简单理解为一个先入后出的列表,其中入的操作称为push,出的操作称为pop。
#!/usr/bin/perl
use 5.010;
@arr = 1..10;
say $#arr + 1; # 10
@var = pop(@arr); #出栈操作1
say $#arr + 1; # 9
$val = pop @arr; #出栈操作2
say $#arr + 1; # 8
pop @arr; # 出栈也可以不使用出栈的数据
say $#arr + 1; # 7
push(@arr, 11); #入栈操作1
say $#arr + 1; # 8
push @arr, 12; #入栈操作2
say $#arr + 1; # 9
push @arr, 13..20; #批量的数字入栈
say $#arr + 1; # 17
push @arr, qw[a b c d]; #批量的字符入栈
say $#arr + 1; # 21
@newarr = 'a'..'z';
push @arr, @newarr; #其他数组的数据批量入栈
say $#arr + 1; # 47
for $var (@arr) {
print $var . " ";
}
say;
栈 shift 和 unshift操作
pop和push针对的是数组尾部的元素,而shift和unshift针对的是数组头部的元素,用法一致,不多做解释
#!/usr/bin/perl
@arr = 1..10;
$var = shift @arr;
unshift @arr, 'newElement';
splice 移接操作
基本格式([]表示可选参数): [@RECEIVE_ARR] = splice @ARR_NAME start_index [splice_number] [replace_list]
分别对每一个参数做解释
代码示例如下
#!/usr/bin/perl
use 5.010;
@arr = 'a'..'z'; # a - z 26个字母
@removed = splice @arr, 14; #移除下标14以后的所有元素
say "first removed : @removed"; #输出第一次移除的元素 o - z
@removed = splice @arr, 0, 7; #移除下标0之后7个元素
say "second removed : @removed"; #输出第二次移除的元素 a - g
@removed = splice @arr, 0, 7, 1..10; #移除下标0之后7个元素,然后补充1 - 10 10个数字元素
say "the third time removed : @removed"; #输出第三次移除的元素 h - n 注意第二次移除后元素下标的重新调整
say "current arr : @arr";
数组可以使用@符号直接内插到字符串中,同$变量的内插一样,但也导致了@符号的使用限制,需要在实际编写脚本时注意
例如
#!/usr/bin/perl
use 5.010;
@arr = 1..10;
$str = "countdown: @arr";
say $str;
# email 和数组内插的 符号冲突问题解决
$email = "[email protected]"; #这会被perl认为是内插了一个qq的数组,错误的写法
say $email;
$email = '[email protected]'; #使用单引号限制转义,正确的写法
say $email;
$email = "11111\@qq.com"; #手动转义,比较麻烦,也是正确的写法
say $email;
reserver反置数组
基本格式:reverse arraysOrList
#!/usr/bin/perl
my @numbers = 1..10; # 元素为 1 - 10的数组
my @countdownNumbers = reverse @numbers; # 元素为 10 - 1 的数组
my @countdownNumbers2 = reverse 1..10; # 元素为 10 - 1 的数组
sort 数组排序
基本格式:sort arraysOrList
根据内部的字符编码顺序对元素进行排序
#!/usr/bin/perl
use 5.010;
@words = qw [b a g c d f e]; # 乱序字母
@sortedWords1 = sort @words; # 排序后 a b c d e f g
@sortedWords2 = sort qw /b a g c d f e/; # 效果与上例相同
say "@words\n@sortedWords1\n@sortedWords2";
each 数组遍历
基本格式:($index, $value) = each @array
没次each数组,将返回一组键值对,键为数组元素的下标,值为数组元素的值。
实际上,在有了foreach后,each显得不那么好用,除非你需要针对数组下标进行一些编程,否则使用foreach可能更加方便
each 语法需要 5.012以上版本支持
#!/usr/bin/perl
use 5.012;
my @fruits = reverse sort qw <banana orange watermelon apple>;
# 使用each函数遍历数组
while (my($index, $value) = each @fruits) {
say "current element = $index:$value";
}
# 使用数组下标foreach遍历数组
foreach my $index (0.. $#fruits) {
say "current element = $index:$fruits[$index]";
}
# 使用for循环遍历数组
for(my $index = 0; $index <= $#fruits; $index += 1) {
say "current element = $index:$fruits[$index]";
}
包括以下内容
unless 就是反if ,但相较于if,unless不仅在语义上有点反人类,而且缺少elsif多重判断支持,因而一般使用if即可。
代码示例
#!/usr/bin/perl
use 5.014;
#使用if判断
foreach (1..10) {
my $value = (int rand 10); # 生成一个0 - 9 的随机整数
if ($value == 0) {
# 当条件为真,进入代码块
say "$value";
} elsif($value % 2 == 0) {
say "$value 是个非零偶数";
} else {
say "$value 是个奇数";
}
}
say "-------------分界线-------------";
#使用unless判断
foreach(1..10) {
my $value = (int rand 10);
unless ($value % 2 == 0) {
# 当条件为假,进入代码块
say "$value 是个奇数";
} else {
say "$value 是个偶数";
}
}
while 语句中当条件为真时循环执行代码块,
until 与之相反,两者在语义上皆符合人类语言的理解,因而使用哪一种都是可以的。
当条件为真,将持续执行代码块, 如下示例将依次打印 2 4 6 8 10 两遍
#!/usr/bin/perl
$count = 0;
while($count < 10) {
#当count小于10时
$count += 2;
print "$count\n";
}
print "-------------分界线-------------\n";
$count = 0;
until($count >= 10) {
#直到count>=10
$count += 2;
print "$count\n";
}
for和foreach很大程度上能够混用,这个可以在实际编程过程中,选择自己最喜欢的写法
针对数组变量或者列表的遍历操作,如下三例都将一次打印 1 - 10
#!/usr/bin/perl
@number = 0;
@numbers = 1..3;
foreach $number (@numbers) {
print "$number\n";
}
for $number (@numbers) {
print "$number\n";
}
for $number (1..3) {
print "$number\n";
}
for (qw[1 2 3]) {
print "$_\n"; #注意这例中没有控制变量,而是使用 $_ ,这是perl的默认变量。这种写法也是允许的
}
use 5.010;
for (qw[google apache microsoft]) {
say; #这里相当于 say "$_";
}
for($int = 0; $int < 5; $int += 1) {
say $int;
}
注:
- 上例中number作为foreach循环的控制变量,在循环开始前是有值的,那么它将在每一次循环结束后恢复到原来的值 0 。
- 关于$_ $_是perl中的默认变量,在很多单个参数的场景中被使用,包括循环/判断结构以及各类函数中,具体可以参考https://cn.perlmaven.com/the-default-variable-of-perl,并试试其中的写法
perl 也支持类似C的函数功能对程序进行进一步的封装,子程序的基本格式为
sub 子程序名 {
#这里书写子程序的程序主体
}
子程的调用使用 & 符号 或者在程序名后加() 进行调用
&子程序名;
子程序名();
# 带参数的子程序调用
&子程序名($param1, $param2);
子程序名($param1, $param2);
上述中子程序含参数时,子程序如何获取这些参数呢?perl并没有显式地定义子程序参数地地方。这个时候就可以使用perl的默认参数 $_
#!/usr/bin/perl
use 5.010;
sub mySubroutine {
for $index (0..$#_) {
#从0开始到 $_ 参数的最后一个下标
say "参数$index 值为: $_[$index]";
}
# 更直观一点
say "第一个参数 = $_[0]";
say "第二个参数 = $_[1]";
}
mySubroutine("Hello Subroutine", 2021);
说完程序的参数后,基于我们以往的编程经验,我们很容易联想到返回值的问题,程序的返回值如何定义,如何接收呢?实际上,在子程序执行过程中,最后一次运算的结果将作为子程序的返回值,程序自动识别而不需要你显式地使用类似return关键字进行返回,当然了,你也可以直接使用return返回某个值以结束子程序
代码示例
#!/usr/bin/perl
use 5.010;
sub mySubroutine0 {
"Hello subroutine";
}
sub mySubroutine1 {
}
sub mySubroutine2 {
return "read paramter" if @_ > 0; #如果参数列表大于0,直接返回值
"Hello subroutine";
}
$ret0 = mySubroutine0();
$ret1 = mySubroutine1();
$ret2 = mySubroutine2(1); #传入一个参数
say $ret0; # 输出 Hello subroutine
say $ret1; # 输出 空串
say $ret2; # 输出 read paramter
更多的示例代码如下所示:
#!/usr/bin/perl
use 5.014;
# 声明无返回值的子程序
sub not_ret_func {
# 实际上是有返回值的,最后一行将print函数将返回成功执行的代码1
# 这个返回值通常作用大多数指令的成功执行标志
# 个别场景下会借以进行条件判断
print "hello world \n";
}
# 声明无返回值的子程序
sub has_ret_func {
# 最后一个值是返回值
my $test = "return value";
$test;
}
# 调用
my $ret1 = ¬_ret_func;
say 'func1 return = ' . $ret1 . " func2 return = " . &has_ret_func;
# 声明含参数的子程序
sub has_param_func {
# 默认数组参数$_ 作用子程序的参数列表
$_[0] + $_[1];
}
# 调用含参子程序
my $num1 = 1;
my $num2 = 2;
say $num1 . ' + ' . $num2 . ' = ' . &has_param_func($num1, $num2);
输出如下
[root@localhost test]# chmod 447 sub.pl
[root@localhost test]# ./sub.pl
hello world
func1 return = 1 func2 return = return value
1 + 2 = 3
[root@localhost test]#
``perl
#!/usr/bin/perl
use 5.010;
sub mySubroutine0 {
“Hello subroutine”;
}
sub mySubroutine1 {
}
sub mySubroutine2 {
return “read paramter” if @_ > 0; #如果参数列表大于0,直接返回值
“Hello subroutine”;
}
$ret0 = mySubroutine0();
$ret1 = mySubroutine1();
$ret2 = mySubroutine2(1); #传入一个参数
say $ret0; # 输出 Hello subroutine
say $ret1; # 输出 空串
say $ret2; # 输出 read paramter
[外链图片转存中...(img-62W9inoS-1626155603241)]
更多的示例代码如下所示:
```perl
#!/usr/bin/perl
use 5.014;
# 声明无返回值的子程序
sub not_ret_func {
# 实际上是有返回值的,最后一行将print函数将返回成功执行的代码1
# 这个返回值通常作用大多数指令的成功执行标志
# 个别场景下会借以进行条件判断
print "hello world \n";
}
# 声明无返回值的子程序
sub has_ret_func {
# 最后一个值是返回值
my $test = "return value";
$test;
}
# 调用
my $ret1 = ¬_ret_func;
say 'func1 return = ' . $ret1 . " func2 return = " . &has_ret_func;
# 声明含参数的子程序
sub has_param_func {
# 默认数组参数$_ 作用子程序的参数列表
$_[0] + $_[1];
}
# 调用含参子程序
my $num1 = 1;
my $num2 = 2;
say $num1 . ' + ' . $num2 . ' = ' . &has_param_func($num1, $num2);
输出如下
[root@localhost test]# chmod 447 sub.pl
[root@localhost test]# ./sub.pl
hello world
func1 return = 1 func2 return = return value
1 + 2 = 3
[root@localhost test]#
文章浏览阅读983次。从2005年成立至今,Mendix一直以客户价值为导向精心打磨产品,提升客户、合作伙伴及所有参与方的使用体验。进入中国以来,我们更是以120%的态度践行这一原则。工欲善其事必先利其器,这里的“器”不仅仅在于产品本身,更在于产品背后代表的思维方式,实施合作伙伴的培养与赋能,解决方案架构,项目管理与执行,客户数字化转型的长远的计划与思考等等。只有不断地用先进的理论指导实践,并在实践中迭代成长,才能充分发挥先进生产工具的最大价值,创造多方的共赢局面。因此,我们会建议Mendix客户针对第一期的开发项目认真地_mendix项目
文章浏览阅读2.3w次,点赞41次,收藏255次。MATLAB修改字体大小,加粗,字体样式,字体颜色,线形颜色格式,添加标签,修改标签格式,希腊字母表,图片文本位置等_matlab字体
文章浏览阅读3.6k次。SpringSoource-tool-suite安装为了使用Spring的方便,首先Eclipse安装插件SpringSoource-tool-suite(SpringSoource-tool-suite 是一个基于EclipseIDE开发环境中的用于开发Spring应用程序的插件。利用这个插件,可以方便的在Eclipse平台上开发基于Spring框架的应用)。如下是SpringSoource-to_springsource-tool-suite
文章浏览阅读156次。通过获取mysql状态值将这些状态值传递给服务器并绘制成图片,这样可以观察mysql的工作情况,通常需要获得状态变量有以下Com_update:mysql执行的更新个数Com_select:mysql执行的查询个数Com_insert:mysql执行插入的个数Com_delete:执行删除的个数Com_rollback:执行回滚的操作个数Bytes_received:接受的字节数Bytes_sen..._zabbix slow queries over 3 for 5m
文章浏览阅读4.6k次,点赞3次,收藏14次。正交实验法的由来一、正交表的由来拉丁方名称的由来 古希腊是一个多民族的国家,国王在检阅臣民时要求每个方队中每行有一个民族代表,每列也要有一个民族的代表。数学家在设计方阵时,以每一个拉丁字母表示一个民族,所以设计的方阵称为拉丁方。什么是n阶拉丁方?用n个不同的拉丁字母排成一个n阶方阵(n<26 ),如果每行的n个字母均不相同,每列的n个字母均不相同,则称这种方阵为n*n拉丁方或n阶拉丁方。每个字母在任一行、任一列中只出现一次。_四阶正交拉丁方阵
文章浏览阅读3.6k次。总第482篇2021年 第052篇经典的细粒度情感分析(ABSA,Aspect-based Sentiment Analysis)主要包含三个子任务,分别为属性抽取、观点抽取以及属性-观点..._absa数据标注工具
文章浏览阅读2.1k次。Apple 在 iOS 11.3 中悄悄加入了对“渐进式 Web 应用”(PWA)这一系列新技术的基本支持。是时候看看这些技术是如何生效的?它有什么能力?会遇到哪些挑战?以及如果已经发布了 PWA,又需要了解哪些事情?本文概括介绍了最新发布的 iOS 11.3 对 PWA 的支持情况,以及 PWA 应用开发者需要注意的问题。本文转载自前端之巅作者 Maximiliano Firtman..._pwa的缺点
文章浏览阅读7.6k次,点赞3次,收藏23次。QT 加载文件,图片路径很容易搞混,需要注意的是WINDOW路径分隔符为“\”,QT为“/”,我遇到的路径加载总结为三种情况:(1)绝对路径,文件的整个路径,比如 setWindowIcon(QIcon("F:/QT_PROJECT/QTtest/test/res/123.jpg"));//加载图片绝对路径(2)相对路径 1.第一种情况,新建QT 资源文件,也就..._qt资源图片路径
文章浏览阅读1.4k次。万维链旨在建立一个分布式的未来“银行”,万维链本身是一个分布式的基于数字资产的金融基础设施,任何机构和个人,都可以在万维链上开设自己的业务窗口,提供基于数字资产的存贷、兑换、支付、结算等服务。更加准确的描述,万维链是一个基于区块链的分布式超级金融市场。_wanchain与delphy都是同一个团队的项目吗?你们是不是来圈钱的?
文章浏览阅读2.7k次。1、安装依赖工具// 安装技术依赖yum install -y curl policycoreutils-python openssh-server // 启动ssh服务/设置为开机启动sudo systemctl enable sshdsudo systemctl start sshd2、安装 Postfix 邮件服务器// 安装 postfixsudo yum ins..._linux 安装gitlab服务器
文章浏览阅读1.4k次。LiveNVR配置拉转RTSP传统海康大华安防摄像机直播流输出RTSP/RTMP/HLS/HTTP-FLV如何获取直播流地址1、 Onvif/RTSP流媒体服务2、配置拉转直播流2.1 RTSP获取配置规则2.2 编辑通道配置3、接口获取视频流地址3.1、获取通道直播链接接口3.2、获取HTTP-FLV播放地址示例3.3、获取WS-FLV播放地址示例3.3、获取RTMP播放地址示例3.4、获取HLS播放地址示例3.4、获取RTSP播放地址示例4、浏览器F12查看播放地址5、播放页面快速集成1、 Onvif_公网 支持rtsp、http的摄像头
文章浏览阅读1.7k次,点赞3次,收藏13次。使用Python爬虫批量下载音乐_qq音乐源url怎么下载