m//
模式用来匹配文本,也就是说用来找数据。而s///
用来查找并替换文本,因此能够用来处理文本文件。在有了正则的基础以后,s///
用起来会简单不少。正则表达式
用法格式为:函数
$str =~ s/reg/replacement/FLAGS;
它表示用reg去搜索$str
中的内容,并将搜索出来的内容替换为replacement。scala
1.s///
的斜线能够替换为其余对称的符号(括号类)或相同的符号。code
例如s!!!
、s###
、s%%%
、s()()
、s{}{}
、s<><>
、s[][]
等,还能够混用符号,例如s{}##
、s{}()
等。对象
$str = "ma xiaofang or ma longshuai"; $str =~ s/ma/gao/g; print "$str\n";
第二句直接会替换掉原来的$str
。blog
2.s//
替换的返回值是替换成功的次数(数量)。字符串
例如上面使用全局替换修饰符g
,使得替换了两个"ma",返回值为2,若是去掉全局替换修饰符,则只替换第一个"ma",返回值为1。string
因此,经过s///
返回值能够看成布尔值来作判断:没有替换成功,将返回0,若是替换成功,则返回值至少为1。it
$str ="ma xiaofang or ma longshuai"; print "substituted" if $str =~ s/ma/gao/;
3.还有一种操做符$str !~ s///
,它的用法和=~
是相同的,只不过它转换了布尔逻辑:替换成功时返回false,替换失败时返回1。基础
4.因为分组后会当即将分组捕获的结果保存到特殊变量\1
和$1
中,因此在replacement部分可使用这些变量。
$str = "gao xiaofang or ma longshuai"; $str =~ s/(gao)(.*)(ma)(.*)/\3$2\1$4/; # \1和$1均可以在replacement中使用 print "$str\n"; # 输出ma xiaofang or gao longshuai
除了全局修饰符g
外,m//
可用的修饰符在s///
中基本均可用,最经常使用的修饰符仍是gimsx
。此外,s///
还有本身的修饰符r和e,稍后解释。
$str = "Gao xiaofang or Ma longshuai"; $str =~ s/(gao).* or (ma).*/$2 xiaofang or $1 longshuai/ig; print "$str\n";
再例如,压缩空白:
s/(\s)+/\1/g; # 将多个空白缩减成一个 s/^\s+//; # 去除行首空白 s/\s+$//; # 去除行尾空白 s/^\s+|\s+$//; # 去除行首空白和行尾空白
本来s///
的返回值是替换成功的次数,使用r修饰符,可让这个替换操做返回替换后的字符串。几个注意点:
$str = "ma xiaofang or ma longshuai"; print $str =~ s/Ma/gao/igr,"\n"; # 输出替换后的内容 print "$str\n"; # 原始内容不变 $copy = $str =~ s/Ma/gao/igr,"\n"; # 替换后的内容赋值给新的变量 print "$copy\n"; # 输出替换后的内容
若是不使用r修饰符,想要将替换的内容输出,只能先将其保存到一个新的变量中,而后输出这个变量:
$str = "ma xiaofang or ma longshuai"; ($copy = $str) =~ s/Ma/gao/ig; print "$str\n"; # 原始数据不变 print "$copy\n"; # 替换后的数据
若是上面省略了括号,那么表示$str
被替换,且将成功替换的次数返回给$copy
。
#!/usr/bin/perl $str = "ma xiaofang or ma longshuai"; $copy = $str =~ s/Ma/gao/ig; print "$str\n"; # 输出gao xiaofang or gao longshuai print "$copy\n"; # 输出2
r修饰符在map函数中很是好用,它能够替换一个列表中的某些元素。
例如,下面的map将@list
中首字母大写的单词替换为小写。须要注意的是这里使用了{}
。
@list = qw(Ma longshuai Gao xiaofang); @new_list = map {s/([A-Z])([a-z]+)/\L\1\E\2/rg} @list; print "@new_list\n";
e是一个超神的修饰符,它可让replacement部分看成一个后执行的表达式。
$str="ma longshuai or ma xiaofang"; $str =~ s/ma/$& x 2/eg; print $str,"\n";
执行上面的程序,它将输出"mama longshuai or mama xiaofang"
上面的过程大体为:搜索字符串"ma",而后将其保存到特殊变量$&
中,在replacement部分,将其重复一次,因此获得"mama"。
甚至,能够用sprintf直接格式化输出替换后的内容。
split函数用于将字符串分割为一个列表(因此在标量上下文返回的是列表的大小)。
split用法以下:
split /pattern_sep/,$string,limit
其中pattern_sep用于指定分隔符,容许使用正则表达式(通常都是很简单的正则),且能够指定多个分隔符。limit表示最多分割为几个元素,若是指定为1(默认),则表示尽量多地分隔。,
例如,用split分割字符串abc:def::1234:xyz
,分隔符指定为:
$str="abc:def::1234:xyz"; @list = split /:/,$str; print "list: [@list]\n"; print "list_size: ",scalar(@list),"\n";
上面的字符串分割后将有5个元素:abc,def,空,1234,xyz。
能够加上一个limit参数,限制最多分隔为多少个元素,例如上面指定limit=2,表示只分隔一次:
$str="abc:def::1234:xyz"; @list = split /:/,$str,2; # 返回"abc","def::1234:xyz"两个元素
split在分割字符串的时候,若是分割后字符串首部会出现空字串,split会保留这些空元素,但若是是尾部空字串,则舍弃。
例如:
$str=":::abc:def:1234:xyz::::"; @new_list=join(".",split /:/,$str); print "@new_list\n"; # 输出:...abc.def.1234.xyz
上面使用了join函数,指定了用"."将split后列表中的各元素链接起来。
split能够指定多个分隔符,且可使用正则表达式来表示。
例如:
$str="abc:def::12:xyz"; @list = split /::/,$str); # 返回:"abc:def","12:xyz" @list = split /[:]+/,$str); # 返回:"abc","def","12","xyz" @list = split /[:0-9]/,$str); # 返回:"abc","def","","","","","xyz"
若是不设置分隔符,那么将认为全部的空白(包括行首空白)都是分隔符,且会将连续的多个空白(即便是多个连续的空行)自动压缩看成一个分隔符,但同时它必须也省略第二个字符串参数。也就是说,这时只能对$_
进行处理。若是省略了分隔符,却设置了待处理的字符串参数,则返回空。
$_="abc 123 xyz\tmn\t\tdef\n\nABC"; @arr=split; print "@arr"; #输出:abc 123 xyz mn def ABC
对省略分隔符作个总结:只要是空白,不管是否在行首,不管是不是换行符,全部连续空白都会被看成单个分隔符。
因此它有点相似于split /\s+/,$str
的行为,只不过指定了分隔符的话就会保留行首一个空白。
还能够指定空分隔符,它会将字符串中的每一个字符都分隔。
$str="abcdef"; print join(",",split //,$str); # 输出a,b,c,d,e,f
通常来讲,分隔符的正则都很简单,若是须要写复杂的模式,请避免在分隔符正则中使用用于分组的括号,由于括号会被看成分隔符。若是想要使用括号,则可使用非捕获分组(?:)
的形式。
join函数用于将列表中各个元素用给定字符链接起来,和split的行为有点相反。它返回一个列表。
join用法以下:
join $sep,$list
其中$sep
只能是字符串,这一点和split不同。
例如:
print join "-",a,b,c,d,efg; # 输出:"a-b-c-d-efg"
能够将split后的结果用join换一个分隔符链接起来:
$str="abc:def::1234:xyz"; @new_list = join(",",split /:/,$str); print "@new_list\n"; # 输出:abc,def,,1234,xyz