Perl字符串处理


众所周知Perl处理字符串的功能非常强大,Perl(Practical Extraction and Reporting language)处理格式的功能也非常强大,这里就介绍一些Perl的格式和字符串处理常见方法与函数。
字符串的内置函数有:
chomp, chop, chr, crypt, fc, hex, index, lc, lcfirst, length, oct, ord,
pack, q//, qq//, reverse, rindex, sprintf, substr, tr///, uc, ucfirst, y///
分为几类:
字符大小写转换类:
lc:(lower case)将后面的字母转换为小写,是\L的实现
lcfirst:将后面第一个字母转换为小写,是\l的实现
uc:(uppercase)将后面的字母转换为大写,是\U的实现
ucfirst:将后面第一个字母转换为大写,是\u的实现
fc:(foldcase)和lc基本等价,只不过fc可以处理UTF-8类的字母
字符处理类函数:
chomp:去除行尾换行符
chop:去除行尾字符,后文详细示例chop
reverse:反转列表、标量字符串、hash,后文详细示例[reverse(#blogreverse)]
substr:获取字串,后文详细示例substr
tr///:字符映射,见tr///
y///:等价于tr///
字符位置索引:
index:获取字符所在索引位置,后文详细示例index和rindex
rindex:也是获取字符所在索引位置,后文详细示例index和rindex
进制转换类:
hex:将16进制转换为十进制。当字符以0x或x开头时会自动被认为是十六进制数
oct:将8进制转换为十进制。当字符以0开头时会自动被当作8进制数
ord:将字符串的第一个字符转换为ascii码
chr:将ascii转换为对应的字符
其他类:
crypt:(暂时略)
length:返回字符串字符数量,后文详细示例length
pack:(暂时略)
q//:相当于给字符串加单引号(quote)
qq//:相当于给字符串加双引号(double quote)
sprintf:(略)printf的不输出版,不用于输出,而用于返回本该输出的内容
单双引号和反引号
perl对待单双引号的方式和shell有点类似:
单引号内,只有反斜线的转义效果存在(如\n不再是换行),其它全都当作字面符号(单引号自身除外)
双引号内,反斜线、反斜线序列(\n,\t...)、变量替换都允许
反引号内,内容会交给shell执行
'freeoa'
'freeoa\'s girl friend'
'freeoa\n' # 这里没有换行
"freeoa\n" # 换行了
'freeoa
girl friend' # 换行了,因为这里的换行是字面符号,不是\n
'freeoa\\n' # 换行了
"freeoa $var" # 变量替换
有以下反斜线序列(转义序列):
\n
\r
\t
\l # 将下个字母转换为小写
\L # 将后面的多个字母都转换为小写,直到遇到\E
\u # 将下个字母转换为大写
\U # 将后面的多个字母都转换为大写,直到遇到\E
\Q # 和\E之间的所有字符都强制当作字面符号
\E # \L、\U和\Q的结束符号
但即使没有"\E",到了字符串结束的地方,转义序列就会结束。例如:
print "\Uabc"."xyz\n" # 输出ABCxyz
print "abc"."x\Eyz\n" # 输出abcxyz
反引号内的字符串会交给shell执行。这是和操作系统交互的一种方式,支持操作系统的管道、重定向等特性。另一种方式是使用system函数。
$mydatetime = `date +"%F %T"`;
print $mydatetime,"\n";
默认情况下,反引号内的内容会被perl先按照双引号的方式进行解析,然后传递给操作系统的shell执行。所以当有变量替换时会进行变量替换:
$name="freeoashuai";
$msg=`echo $name`; # 替换为echo freeoashuai,然后交给shell
print $msg;
如果不想先被perl解析,可以使用qx和单引号结合的方式,关于qx,见下文。
$name="freeoashuai";
$msg=qx'echo ha $name hei'; # 不会替换为freeoashuai,而是将$name替换为空交给shell
print $msg;
引号的文本形式:q、qq和qx
q等价于单引号,qq等价于双引号,qx等价于反引号。更多q系列的用法可参考《q_qq_qr_qw_qx》。
q(hello world) # 等价于'hello world'
qq(hello world) # 等价于"hello world"
qx(echo hello world) # 等价于`echo hello world`
上面的括号可以替换为其它符号,只要前后能配对(特指括号类)或者一致即可:
qq{ hello }
qq! hello !
qq# hello #
qq% hello %
字符串连接和重复
字符串连接使用点(.),下面是等价的:
abc.cde
abccde
字符串重复使用小写字母"x",后跟一个重复倍数。如果倍数是一个小数,如3.2,则会取整。如果倍数小于1,则取整为0,倍数为0返回空。
"abc" x 3
"abc" x 3.2
都将输出"abcabcabc"。
"abc" x 0.4 # 返回空
"x"符号左边会强制转换为字符串。
03 x 3 # 返回333
"03" x 3 # 返回030303
3 x 3 # 返回333
3.2 x 3 # 返回3.23.23.2
数值和字符串的类型自动转换
什么时候转换,以及向哪个方向转换,取决于操作符。
例如算数运算符(+-*/等)需要的是数值,会强制转换为数值。"."操作符需要的是字符串,会强制转换为字符串。
"0333" + 22 # 返回355
"033".22 # 返回03322
033.22 # 返回2722,033表示8进制,转换为十进制为27(3*8+3)
要注意的一个地方,数值开头的字符串也可以强制转换为数值。但只能转换数值开头(允许前导空白)的字符串:
"12abc" * 3 # 36
"abc12" * 4 # 0
" 12abc" * 3 # 36
两种类型的操作符一起用的时候,会按照优先级进行运算:
"abc".5*3 # 返回abc15,乘法先运算
"abc".5 + 3 # 返回3,"."先运算
"abc".(5+3) # 返回abc8
Heredoc
perl中也支持heredoc,所谓heredoc,即表示将后面的内容当作文档。既然是文档,就需要有文档起始符和文档结束符,分别标识文档从哪里起始,到哪里结束。一般来说,所有支持heredoc的语言,文档起始符和文档结束符都必须相同(一般使用EOF或eof作为起始符和结束符),且结束符必须单独占行且顶格书写。
perl中支持的heredoc格式如下,以print为例:
print <<EOF;
line1
line2
line3
EOF
这里以EOF作为文档起始符和结束符
起始符EOF后面必须加上分号结尾,分号后的所有内容都忽略(即使它后面的不是注释内容)
结束符EOF单独占用一行,且顶格书写
起始符和结束符中间是怎样的数据,输出时就是怎样的数据
perl的heredoc还有自己的特性,可以为起始符加上单引号和双引号以及其它符号。加单双引号后的效果和一般单引号、双引号的能力是一样的:
单引号是强引用
双引号是弱引用
不加引号等价于加双引号
加反引号`,则将字符串放进shell环境执行
加单双引号:
$name="freeoashuai";
print <<'EOF';
haha
\$name # 反斜线转义功能失效
$name # 变量无法替换
EOF
print <<"EOF";
haha
\$name # 反斜线成功转义
$name # 变量成功替换
EOF
加反引号:
print <<`EOF`;
date +"%F %T"
EOF
可以将heredoc直接赋值给变量:
$msg = <<EOF;
HELLO
WORLD
EOF
print $msg; # $msg不要加换行符,因为$msg是一个heredoc,自带换行符。
熟悉其最强大的三个函数:substr、pack、unpack。
1、大小写处理函数 lc(转为小写) uc(转为大写) 。
$text="zhengwen feng";
$text2=lc $text;
$text3=uc $text;
print "$text2\n";
print "$text3\n";
2、将第一字母变为小写(lcfirst),将第一个字母大写(ucfirst)。
$string="zheng";
$string2=lcfirst $string;
$string3=ucfirst $string;
print "$string2\n";
print "$string3\n";
3、顺序查找string位置(index),逆序查找string位置(rindex)。index在字串中找尋某一子字串的起始位置。
$string="zheng wen feng zheng wen feng";
$position1=index($string,"wen");
$position2=index($string,"wen",10);
$position3=rindex($string,"zheng");
$position4=rindex($string,"zheng",10);
print "$position1,$position2,$position3,$position4\n";
#!/usr/bin/Perl
$str="ABCDEFG1234567";
$a="12";
$pos=index($str,$a);
print$pos,"\n";
[hto@localhost]$./tipind.pl
7
4、获取子串函数substr,功能非常强大,可以直接支持以一个字符串代替字符串的一个子串。
$text="zheng wenfeng 爱 KittyKitty";
$replace_to="爱";
$replace_with="喜欢";
substr($text,index($text,$replace_to),length($replace_to),$replace_with);
print "$text\n";
5、字符串中取串长(字符数量)-length
#!/usr/bin/Perl
$str="abCD99e";
$strlen=length($str);
print$strlen,"\n";
[htog@localhost]$./tiplen.pl
7
8、pack和unpack函数用于字符串的打包和解包,功能非常强大,支持多种打包格式字符串处理的。
$decimal=17;
$newdecimal=unpack("B32",pack("N",$decimal));
print "$newdecimal\n";
$string="张大华爱中国";
@array1=unpack("c*",$string);
@array2=unpack("C*",$string);
print (join(",",@array1),"\n");
print (join(",",@array2),"\n");
$string1=pack("c*",@array1);
$string2=pack("C*",@array2);
print "$string1\n";
print "$string2\n";
9、打印格式-sprintf
$value=1234.56789;
print sprintf "%.4f\n",$value;
10、字符串比较函数 eq、ne、cmp、lt、gt、le、ge,使用cmp就好。绝不能用'==',要用eq,正确的做法是:不论整形Perl字符串,都用eq。
$string1="大华";
$string2="大华";
if($string1 eq $string2){
print "$sting1==$string2\n";
}
if($string1 ne $string2){
print "$string1!=$string2\n";
}
if( ($string1 cmp $string2)==0){
print "$string1==$string2\n";
}
$string1="zheng";
$string2="Kitty";
if($string1 lt $string2){
print "left < right \n";
}
if($string1 gt $string2){
print "left > right \n";
}
if($string1 le $string2){
print "left < right \n";
}
if($string1 ge $string2){
print "left > right \n";
}
11、字符分割操作-split
@数组=split(pattern,串),将Perl字符串用某模式分成多个单词。
#!/usr/bin/Perl
$str="ABCDEiFG12i34567";
@array=split(//,$str);按空格分
foreach(@array){
print$_,"\n";
}
[hto@localhost]$./tip.pl
ABCDEi
FG12i
345
6
7
@array=split(/+/,$line);当一行中各单词间的空格多于一个时。
空格和TAB混杂情况下的split
[hto@localhost]$vitip.pl
#!/usr/bin/Perl
$str="ABCDEiFG12i34567";
@array=split(/\t/,$str);
foreach(@array){
print$_,"\n";
}
[hto@localhost]$./tip.pl
ABCDEiFG12i
34567
只分了两份,为什么?因为同时满足TAB和空格的只有一处,所以必须加[]。
@array=split(/[\t]/,$str);现在才是真正的按空格和TAB分
[hto@localhost]$./tip.pl
ABCDEi
FG12i
345
6
7
但还是有缺陷,TAB和空格相连时,TAB被认为是空格划分的子串,或者空格被认为是TAB划分的子串。
$string="张大华爱中国";
@array=split(//,$string);#这种方法无法将其进行分成"张","大","华","爱","中","国"等单字
print (join(",",@array),"\n");
12、演示中文字符夹带英文字符的反序(使用了多个函数)
print "------begin-----\n";
$string1="中国love!张大华";
@array=unpack("C*",$string1);
$length=$#array;#此数组的最后一个下标
for(;$length>=0;){
if($array[$length]<=128){
#英文或者标点
push(@array2,$array[$length]);
$length=$length-1;
}
else{
#中文字符
push(@array2,$array[$length-1]);
push(@array2,$array[$length]);
$length=$length-2;
}
}
$string2=pack("C*",@array2);
print "$string2\n";
$dir=dir;
print qx/$dir/;
@name=qw/zheng wen feng Kitty Kitty/;
print join(",",@name);
13、字符合并操作-join
用join定义Perl字符串数组格式符号(缺省)必须与qw()合用。
语法:join($string,@array)
@array=qw(onetwothree);
$total="one,two,three";
@array=qw(onetwothree);
$total=join(":",@array);
$total="one:two:three";
14、匹配数组内元素字串-grep
@array=("one","on","in");
$count=grep(/on/,@array);
查询结果赋值给单变量
@array=("one","on","in");
@result=grep(/on/,@array);
查询结果赋值给数组
2
one
on
15、字符串连接-'.='
关于perl字符串连接的方法讨论。
$line = $line."456";
这个语句中,line要被计算两次。
$line .= "456" ;
运算符',',常用于输出:
print "金",$v1;
print $str,"\n\n";
'.'运算符和','类似,也是Perl字符串相加但通常只用于print而'.'可以用在任何Perl字符串相加的地方。
print '12345大家來'."helloworld";
結果变成:12345大家來helloworld
16、重复连接运算符号-x
print"OK"x4;
結果变成:
OKOKOKOK
这个计算一次就可以了。Perl字符串的连接可以连接整形和字符形,整形也被当作字符型处理,没有printf里的%d问题。
17、双引号字符串中的转义符
符号 含义
\n 换行
\r 回车
\t 制表符
\f formfeed
\b 退格
\a 响铃
\e escape(ASCII中的escape字符)
\007 任何八进制值(这里是,007=bell(响铃))
\x7f 任何十六进制值
\cC 一个控制符(这里是,ctrl+c)
\\ 反斜线
\" 双引号
\l 下个字符小写
\L 接着的字符均为小写直到\E
\u 下个字符大写
\U 接着的字符均为大写直到\E
\Q 在non-word字符前加上\,直到\E
\E 结束\L,\E和\Q
17、chop和chomp
1.chop去除行尾字符,返回行尾去除的字符
2.修改hash的时候,去除每个value的最后一个字符,而不是最后一个key,并返回最后一个value被删除的字符
3.修改列表时,去除每个元素的最后一个字符
1.修改字符串
$str="abnc";
print chop $str; # 输出c
print $str; # 输出abn
2.修改hash(目的与结果均不确定)
%myhash=(name => "freeoa",prov => "jiangxi",sch => "linchuan");
$choped = chop %myhash;
while(($key,$value) = each %myhash){
print $key,":","$value\n";
}
print "=" x 9,"\n";
print "$choped";
3.修改列表
@list=qw(aaa bbb ccc ddd);
chop @list; # 返回aa bb cc dd
print "@list";
《移除字符串中的字符》
18、reverse
用于反转列表、标量字符串、hash。
1.反转列表时,将返回反序的列表
2.当放在标量上下文时,将做字符串反转
3.当反转hash时,将把value反转成key,所以当value有重复值时,反转时会丢弃一部分键值
4.reverse不是作用在原始内容上的,而是通过返回值返回反转结果
反转列表:将元素反转
@arr=qw(abc def ghi);
@arr=reverse @arr;
print "@arr\n"; # 输出(ghi def abc)
say join(",",reverse "hello","world"); # 输出:world,hello
标量上下文下:串联各元素得到一个标量,然后反转这个标量,即使反转目标是列表
@arr=qw(aA bB cC dD);
print scalar reverse @arr; # 输出:DdCcBbAa
print "\n";
print @arr; # 输出:aAbBcCdD
反转字符串:
print scalar reverse "hello"; # 输出olleh
反转hash:会把value反转成key,所以value重复时,将丢弃一部分键值
%arr=qw(aA bB cC dD);
%arr1=reverse %arr;
while(($key,$value)=each %arr1){
print "$key -> ","$value","\n";
}
执行结果:
dD -> cC
bB -> aA
19、substr
用于从给定字符串中提取出一段子字符串。
用法:
substr STRING,OFFSET,LENGTH,REPLACEMENT
substr STRING,OFFSET,LENGTH
substr STRING,OFFSET
其中:
1.offset从0开始计算
2.offset为负数时,表示从尾部位移(从-1开始计算)往前位移
3.length如果忽略,则从offset处开始取到最尾部
4.length为负数时,length则表示从后往前的位移位置,所以将提取从offset到length处的子串
5.replacement替换string中提取出来的字串。需要注意两点:
5.1.加了replacement,将返回提取的子串
5.2.但源字符串STRING已被替换
use 5.010;
$str="love your everything";
say substr $str,5; # 输出:your everything
say substr $str,-10; # 从后往前取:everything
say substr $str,5,4; # 从前往后取4个字符:your
say substr $str,5,-3; # 从位移5取到位移-3(从后往前算):your everyth
say substr $str,5,4,"fairy's"; # 替换源字符串,但返回提取子串:your
say $str; # 源字符串已被替换:love fairy's everything
可以将substr函数作为左值(lvalue),这样可以修改源变量,就像给了replacement参数一样:
use 5.010;
$str="love your everything";
substr($str,5,4) = "freeoa's";
say $str; # 源字符串已被替换:love freeoa's everything
还可以用绑定操作符(=~)只对字串的某部分进行操作。
my $rstr='It is some perl articles on freeoa.net, on sites freeoa has more freeoa.net';
substr($rstr,-30)=~s/freeoa/OaFree/g;
substr与index能做到的事用正则也能办到,通常前者要快一点,因为其没有正则表达式的额外的负担:后者总是区分大小写,不必担心元字符,也不会动用任何内存变量。
返回被替换的字串
my $str='freeoa.net';
my $reped_str=substr($str,0,6,"Site of FreeOA");
say "$str\n$reped_str";
>
Site of FreeOA.net
freeoa
20、index和rindex
它们用来找出给定字符串中某个子串或某个字符的索引位置。
用法:
(r)index STRING,SUBSTR,POSITION
(r)index STRDING,SUBSTR
1.index用于搜索STRING中第一次出现SUBSTR的位置,rindex则搜索最后一次出现的SUBSTR位置
2.如果省略position,则从起始位置(从0开始计算)开始搜索第一次出现的子串
3.给定position,则从position处开始搜索,如果是rindex,则是找position左边的
4.如果STRING中找不到SUBSTR,则返回-1
use 5.010;
$str="love you and your everything";
say index $str,"you"; # 输出:5
say index $str,"yours"; # 输出:-1
say index $str,"you",136; # 输出:-1
say index $str,"you",6; # 从offset=6之后搜索,输出:13
say rindex $str,"you"; # 输出:13
say rindex $str,"you",10; # 找出offset=10左边的最后一个you,输出:5
21、length
用于返回字符串的字符数量,不是字节数。如果是字节数,则采用unicode模块。
下面的例子中,将输出11:
$str="hello world";
print length $str;
length不能直接作用于数组和hash来统计元素个数。想要统计个数:
1.对于数组,直接将其放在标量上下文即可
2.对于hash,可使用keys函数返回hash键,然后放进标量上下文
# 数组元素个数
@arr=qw(aaa bb ccc ddd eee ff);
print scalar @arr; # 输出6
# hash元素个数
%myhash=qw(aaa bb ccc ddd eee ff);
print scalar keys %myhash;
如果length的对象未定义,则返回undef。如果length的对象没有字符但已定义,则返回0。
字符串的内置函数有:
chomp, chop, chr, crypt, fc, hex, index, lc, lcfirst, length, oct, ord,
pack, q//, qq//, reverse, rindex, sprintf, substr, tr///, uc, ucfirst, y///
分为几类:
字符大小写转换类:
lc:(lower case)将后面的字母转换为小写,是\L的实现
lcfirst:将后面第一个字母转换为小写,是\l的实现
uc:(uppercase)将后面的字母转换为大写,是\U的实现
ucfirst:将后面第一个字母转换为大写,是\u的实现
fc:(foldcase)和lc基本等价,只不过fc可以处理UTF-8类的字母
字符处理类函数:
chomp:去除行尾换行符
chop:去除行尾字符,后文详细示例chop
reverse:反转列表、标量字符串、hash,后文详细示例[reverse(#blogreverse)]
substr:获取字串,后文详细示例substr
tr///:字符映射,见tr///
y///:等价于tr///
字符位置索引:
index:获取字符所在索引位置,后文详细示例index和rindex
rindex:也是获取字符所在索引位置,后文详细示例index和rindex
进制转换类:
hex:将16进制转换为十进制。当字符以0x或x开头时会自动被认为是十六进制数
oct:将8进制转换为十进制。当字符以0开头时会自动被当作8进制数
ord:将字符串的第一个字符转换为ascii码
chr:将ascii转换为对应的字符
其他类:
crypt:(暂时略)
length:返回字符串字符数量,后文详细示例length
pack:(暂时略)
q//:相当于给字符串加单引号(quote)
qq//:相当于给字符串加双引号(double quote)
sprintf:(略)printf的不输出版,不用于输出,而用于返回本该输出的内容
单双引号和反引号
perl对待单双引号的方式和shell有点类似:
单引号内,只有反斜线的转义效果存在(如\n不再是换行),其它全都当作字面符号(单引号自身除外)
双引号内,反斜线、反斜线序列(\n,\t...)、变量替换都允许
反引号内,内容会交给shell执行
'freeoa'
'freeoa\'s girl friend'
'freeoa\n' # 这里没有换行
"freeoa\n" # 换行了
'freeoa
girl friend' # 换行了,因为这里的换行是字面符号,不是\n
'freeoa\\n' # 换行了
"freeoa $var" # 变量替换
有以下反斜线序列(转义序列):
\n
\r
\t
\l # 将下个字母转换为小写
\L # 将后面的多个字母都转换为小写,直到遇到\E
\u # 将下个字母转换为大写
\U # 将后面的多个字母都转换为大写,直到遇到\E
\Q # 和\E之间的所有字符都强制当作字面符号
\E # \L、\U和\Q的结束符号
但即使没有"\E",到了字符串结束的地方,转义序列就会结束。例如:
print "\Uabc"."xyz\n" # 输出ABCxyz
print "abc"."x\Eyz\n" # 输出abcxyz
反引号内的字符串会交给shell执行。这是和操作系统交互的一种方式,支持操作系统的管道、重定向等特性。另一种方式是使用system函数。
$mydatetime = `date +"%F %T"`;
print $mydatetime,"\n";
默认情况下,反引号内的内容会被perl先按照双引号的方式进行解析,然后传递给操作系统的shell执行。所以当有变量替换时会进行变量替换:
$name="freeoashuai";
$msg=`echo $name`; # 替换为echo freeoashuai,然后交给shell
print $msg;
如果不想先被perl解析,可以使用qx和单引号结合的方式,关于qx,见下文。
$name="freeoashuai";
$msg=qx'echo ha $name hei'; # 不会替换为freeoashuai,而是将$name替换为空交给shell
print $msg;
引号的文本形式:q、qq和qx
q等价于单引号,qq等价于双引号,qx等价于反引号。更多q系列的用法可参考《q_qq_qr_qw_qx》。
q(hello world) # 等价于'hello world'
qq(hello world) # 等价于"hello world"
qx(echo hello world) # 等价于`echo hello world`
上面的括号可以替换为其它符号,只要前后能配对(特指括号类)或者一致即可:
qq{ hello }
qq! hello !
qq# hello #
qq% hello %
字符串连接和重复
字符串连接使用点(.),下面是等价的:
abc.cde
abccde
字符串重复使用小写字母"x",后跟一个重复倍数。如果倍数是一个小数,如3.2,则会取整。如果倍数小于1,则取整为0,倍数为0返回空。
"abc" x 3
"abc" x 3.2
都将输出"abcabcabc"。
"abc" x 0.4 # 返回空
"x"符号左边会强制转换为字符串。
03 x 3 # 返回333
"03" x 3 # 返回030303
3 x 3 # 返回333
3.2 x 3 # 返回3.23.23.2
数值和字符串的类型自动转换
什么时候转换,以及向哪个方向转换,取决于操作符。
例如算数运算符(+-*/等)需要的是数值,会强制转换为数值。"."操作符需要的是字符串,会强制转换为字符串。
"0333" + 22 # 返回355
"033".22 # 返回03322
033.22 # 返回2722,033表示8进制,转换为十进制为27(3*8+3)
要注意的一个地方,数值开头的字符串也可以强制转换为数值。但只能转换数值开头(允许前导空白)的字符串:
"12abc" * 3 # 36
"abc12" * 4 # 0
" 12abc" * 3 # 36
两种类型的操作符一起用的时候,会按照优先级进行运算:
"abc".5*3 # 返回abc15,乘法先运算
"abc".5 + 3 # 返回3,"."先运算
"abc".(5+3) # 返回abc8
Heredoc
perl中也支持heredoc,所谓heredoc,即表示将后面的内容当作文档。既然是文档,就需要有文档起始符和文档结束符,分别标识文档从哪里起始,到哪里结束。一般来说,所有支持heredoc的语言,文档起始符和文档结束符都必须相同(一般使用EOF或eof作为起始符和结束符),且结束符必须单独占行且顶格书写。
perl中支持的heredoc格式如下,以print为例:
print <<EOF;
line1
line2
line3
EOF
这里以EOF作为文档起始符和结束符
起始符EOF后面必须加上分号结尾,分号后的所有内容都忽略(即使它后面的不是注释内容)
结束符EOF单独占用一行,且顶格书写
起始符和结束符中间是怎样的数据,输出时就是怎样的数据
perl的heredoc还有自己的特性,可以为起始符加上单引号和双引号以及其它符号。加单双引号后的效果和一般单引号、双引号的能力是一样的:
单引号是强引用
双引号是弱引用
不加引号等价于加双引号
加反引号`,则将字符串放进shell环境执行
加单双引号:
$name="freeoashuai";
print <<'EOF';
haha
\$name # 反斜线转义功能失效
$name # 变量无法替换
EOF
print <<"EOF";
haha
\$name # 反斜线成功转义
$name # 变量成功替换
EOF
加反引号:
print <<`EOF`;
date +"%F %T"
EOF
可以将heredoc直接赋值给变量:
$msg = <<EOF;
HELLO
WORLD
EOF
print $msg; # $msg不要加换行符,因为$msg是一个heredoc,自带换行符。
熟悉其最强大的三个函数:substr、pack、unpack。
1、大小写处理函数 lc(转为小写) uc(转为大写) 。
$text="zhengwen feng";
$text2=lc $text;
$text3=uc $text;
print "$text2\n";
print "$text3\n";
2、将第一字母变为小写(lcfirst),将第一个字母大写(ucfirst)。
$string="zheng";
$string2=lcfirst $string;
$string3=ucfirst $string;
print "$string2\n";
print "$string3\n";
3、顺序查找string位置(index),逆序查找string位置(rindex)。index在字串中找尋某一子字串的起始位置。
$string="zheng wen feng zheng wen feng";
$position1=index($string,"wen");
$position2=index($string,"wen",10);
$position3=rindex($string,"zheng");
$position4=rindex($string,"zheng",10);
print "$position1,$position2,$position3,$position4\n";
#!/usr/bin/Perl
$str="ABCDEFG1234567";
$a="12";
$pos=index($str,$a);
print$pos,"\n";
[hto@localhost]$./tipind.pl
7
4、获取子串函数substr,功能非常强大,可以直接支持以一个字符串代替字符串的一个子串。
$text="zheng wenfeng 爱 KittyKitty";
$replace_to="爱";
$replace_with="喜欢";
substr($text,index($text,$replace_to),length($replace_to),$replace_with);
print "$text\n";
5、字符串中取串长(字符数量)-length
#!/usr/bin/Perl
$str="abCD99e";
$strlen=length($str);
print$strlen,"\n";
[htog@localhost]$./tiplen.pl
7
8、pack和unpack函数用于字符串的打包和解包,功能非常强大,支持多种打包格式字符串处理的。
$decimal=17;
$newdecimal=unpack("B32",pack("N",$decimal));
print "$newdecimal\n";
$string="张大华爱中国";
@array1=unpack("c*",$string);
@array2=unpack("C*",$string);
print (join(",",@array1),"\n");
print (join(",",@array2),"\n");
$string1=pack("c*",@array1);
$string2=pack("C*",@array2);
print "$string1\n";
print "$string2\n";
9、打印格式-sprintf
$value=1234.56789;
print sprintf "%.4f\n",$value;
10、字符串比较函数 eq、ne、cmp、lt、gt、le、ge,使用cmp就好。绝不能用'==',要用eq,正确的做法是:不论整形Perl字符串,都用eq。
$string1="大华";
$string2="大华";
if($string1 eq $string2){
print "$sting1==$string2\n";
}
if($string1 ne $string2){
print "$string1!=$string2\n";
}
if( ($string1 cmp $string2)==0){
print "$string1==$string2\n";
}
$string1="zheng";
$string2="Kitty";
if($string1 lt $string2){
print "left < right \n";
}
if($string1 gt $string2){
print "left > right \n";
}
if($string1 le $string2){
print "left < right \n";
}
if($string1 ge $string2){
print "left > right \n";
}
11、字符分割操作-split
@数组=split(pattern,串),将Perl字符串用某模式分成多个单词。
#!/usr/bin/Perl
$str="ABCDEiFG12i34567";
@array=split(//,$str);按空格分
foreach(@array){
print$_,"\n";
}
[hto@localhost]$./tip.pl
ABCDEi
FG12i
345
6
7
@array=split(/+/,$line);当一行中各单词间的空格多于一个时。
空格和TAB混杂情况下的split
[hto@localhost]$vitip.pl
#!/usr/bin/Perl
$str="ABCDEiFG12i34567";
@array=split(/\t/,$str);
foreach(@array){
print$_,"\n";
}
[hto@localhost]$./tip.pl
ABCDEiFG12i
34567
只分了两份,为什么?因为同时满足TAB和空格的只有一处,所以必须加[]。
@array=split(/[\t]/,$str);现在才是真正的按空格和TAB分
[hto@localhost]$./tip.pl
ABCDEi
FG12i
345
6
7
但还是有缺陷,TAB和空格相连时,TAB被认为是空格划分的子串,或者空格被认为是TAB划分的子串。
$string="张大华爱中国";
@array=split(//,$string);#这种方法无法将其进行分成"张","大","华","爱","中","国"等单字
print (join(",",@array),"\n");
12、演示中文字符夹带英文字符的反序(使用了多个函数)
print "------begin-----\n";
$string1="中国love!张大华";
@array=unpack("C*",$string1);
$length=$#array;#此数组的最后一个下标
for(;$length>=0;){
if($array[$length]<=128){
#英文或者标点
push(@array2,$array[$length]);
$length=$length-1;
}
else{
#中文字符
push(@array2,$array[$length-1]);
push(@array2,$array[$length]);
$length=$length-2;
}
}
$string2=pack("C*",@array2);
print "$string2\n";
$dir=dir;
print qx/$dir/;
@name=qw/zheng wen feng Kitty Kitty/;
print join(",",@name);
13、字符合并操作-join
用join定义Perl字符串数组格式符号(缺省)必须与qw()合用。
语法:join($string,@array)
@array=qw(onetwothree);
$total="one,two,three";
@array=qw(onetwothree);
$total=join(":",@array);
$total="one:two:three";
14、匹配数组内元素字串-grep
@array=("one","on","in");
$count=grep(/on/,@array);
查询结果赋值给单变量
@array=("one","on","in");
@result=grep(/on/,@array);
查询结果赋值给数组
2
one
on
15、字符串连接-'.='
关于perl字符串连接的方法讨论。
$line = $line."456";
这个语句中,line要被计算两次。
$line .= "456" ;
运算符',',常用于输出:
print "金",$v1;
print $str,"\n\n";
'.'运算符和','类似,也是Perl字符串相加但通常只用于print而'.'可以用在任何Perl字符串相加的地方。
print '12345大家來'."helloworld";
結果变成:12345大家來helloworld
16、重复连接运算符号-x
print"OK"x4;
結果变成:
OKOKOKOK
这个计算一次就可以了。Perl字符串的连接可以连接整形和字符形,整形也被当作字符型处理,没有printf里的%d问题。
17、双引号字符串中的转义符
符号 含义
\n 换行
\r 回车
\t 制表符
\f formfeed
\b 退格
\a 响铃
\e escape(ASCII中的escape字符)
\007 任何八进制值(这里是,007=bell(响铃))
\x7f 任何十六进制值
\cC 一个控制符(这里是,ctrl+c)
\\ 反斜线
\" 双引号
\l 下个字符小写
\L 接着的字符均为小写直到\E
\u 下个字符大写
\U 接着的字符均为大写直到\E
\Q 在non-word字符前加上\,直到\E
\E 结束\L,\E和\Q
17、chop和chomp
1.chop去除行尾字符,返回行尾去除的字符
2.修改hash的时候,去除每个value的最后一个字符,而不是最后一个key,并返回最后一个value被删除的字符
3.修改列表时,去除每个元素的最后一个字符
1.修改字符串
$str="abnc";
print chop $str; # 输出c
print $str; # 输出abn
2.修改hash(目的与结果均不确定)
%myhash=(name => "freeoa",prov => "jiangxi",sch => "linchuan");
$choped = chop %myhash;
while(($key,$value) = each %myhash){
print $key,":","$value\n";
}
print "=" x 9,"\n";
print "$choped";
3.修改列表
@list=qw(aaa bbb ccc ddd);
chop @list; # 返回aa bb cc dd
print "@list";
《移除字符串中的字符》
18、reverse
用于反转列表、标量字符串、hash。
1.反转列表时,将返回反序的列表
2.当放在标量上下文时,将做字符串反转
3.当反转hash时,将把value反转成key,所以当value有重复值时,反转时会丢弃一部分键值
4.reverse不是作用在原始内容上的,而是通过返回值返回反转结果
反转列表:将元素反转
@arr=qw(abc def ghi);
@arr=reverse @arr;
print "@arr\n"; # 输出(ghi def abc)
say join(",",reverse "hello","world"); # 输出:world,hello
标量上下文下:串联各元素得到一个标量,然后反转这个标量,即使反转目标是列表
@arr=qw(aA bB cC dD);
print scalar reverse @arr; # 输出:DdCcBbAa
print "\n";
print @arr; # 输出:aAbBcCdD
反转字符串:
print scalar reverse "hello"; # 输出olleh
反转hash:会把value反转成key,所以value重复时,将丢弃一部分键值
%arr=qw(aA bB cC dD);
%arr1=reverse %arr;
while(($key,$value)=each %arr1){
print "$key -> ","$value","\n";
}
执行结果:
dD -> cC
bB -> aA
19、substr
用于从给定字符串中提取出一段子字符串。
用法:
substr STRING,OFFSET,LENGTH,REPLACEMENT
substr STRING,OFFSET,LENGTH
substr STRING,OFFSET
其中:
1.offset从0开始计算
2.offset为负数时,表示从尾部位移(从-1开始计算)往前位移
3.length如果忽略,则从offset处开始取到最尾部
4.length为负数时,length则表示从后往前的位移位置,所以将提取从offset到length处的子串
5.replacement替换string中提取出来的字串。需要注意两点:
5.1.加了replacement,将返回提取的子串
5.2.但源字符串STRING已被替换
use 5.010;
$str="love your everything";
say substr $str,5; # 输出:your everything
say substr $str,-10; # 从后往前取:everything
say substr $str,5,4; # 从前往后取4个字符:your
say substr $str,5,-3; # 从位移5取到位移-3(从后往前算):your everyth
say substr $str,5,4,"fairy's"; # 替换源字符串,但返回提取子串:your
say $str; # 源字符串已被替换:love fairy's everything
可以将substr函数作为左值(lvalue),这样可以修改源变量,就像给了replacement参数一样:
use 5.010;
$str="love your everything";
substr($str,5,4) = "freeoa's";
say $str; # 源字符串已被替换:love freeoa's everything
还可以用绑定操作符(=~)只对字串的某部分进行操作。
my $rstr='It is some perl articles on freeoa.net, on sites freeoa has more freeoa.net';
substr($rstr,-30)=~s/freeoa/OaFree/g;
substr与index能做到的事用正则也能办到,通常前者要快一点,因为其没有正则表达式的额外的负担:后者总是区分大小写,不必担心元字符,也不会动用任何内存变量。
返回被替换的字串
my $str='freeoa.net';
my $reped_str=substr($str,0,6,"Site of FreeOA");
say "$str\n$reped_str";
>
Site of FreeOA.net
freeoa
20、index和rindex
它们用来找出给定字符串中某个子串或某个字符的索引位置。
用法:
(r)index STRING,SUBSTR,POSITION
(r)index STRDING,SUBSTR
1.index用于搜索STRING中第一次出现SUBSTR的位置,rindex则搜索最后一次出现的SUBSTR位置
2.如果省略position,则从起始位置(从0开始计算)开始搜索第一次出现的子串
3.给定position,则从position处开始搜索,如果是rindex,则是找position左边的
4.如果STRING中找不到SUBSTR,则返回-1
use 5.010;
$str="love you and your everything";
say index $str,"you"; # 输出:5
say index $str,"yours"; # 输出:-1
say index $str,"you",136; # 输出:-1
say index $str,"you",6; # 从offset=6之后搜索,输出:13
say rindex $str,"you"; # 输出:13
say rindex $str,"you",10; # 找出offset=10左边的最后一个you,输出:5
21、length
用于返回字符串的字符数量,不是字节数。如果是字节数,则采用unicode模块。
下面的例子中,将输出11:
$str="hello world";
print length $str;
length不能直接作用于数组和hash来统计元素个数。想要统计个数:
1.对于数组,直接将其放在标量上下文即可
2.对于hash,可使用keys函数返回hash键,然后放进标量上下文
# 数组元素个数
@arr=qw(aaa bb ccc ddd eee ff);
print scalar @arr; # 输出6
# hash元素个数
%myhash=qw(aaa bb ccc ddd eee ff);
print scalar keys %myhash;
如果length的对象未定义,则返回undef。如果length的对象没有字符但已定义,则返回0。
该文章最后由 阿炯 于 2024-06-01 18:42:32 更新,目前是第 2 版。