天天看点

【perl脚本】单行循环正则匹配前言场景

前言

今天就没有人能阻止我成为一名脚本工程师了!

场景

在一行字符串中循环查找匹配一类内容,并进行后续操作如替换等;

场景1:删除一段字符串中的数字

这类找到就删除的场景是最简单的,直接借助g就可以搞定了:

#!/usr/bin/perl 

my $str = "hello 123joom, you have 988 error, 1992 warning";
my $res;

$res = ($str =~ s/\d+//g);
print "replace $res time: $str";
           

打印结果:

replace 3 time: hello joom, you have  error,  warning
           

场景2:把一段字符串中的数字之间加上-

这类场景的特点是,按照一定规则匹配上之后会修改变量,使之不在符合之前的规则,因此用while可破:

#!/usr/bin/perl 

my $str = "hello 123joom, you have 988 error, 1992 warning";

while($str =~ /(.*)(\d)(\d)(.*)/){
	$str = $1.$2."-".$3.$4;
}
print "$str";
           

打印结果:

hello 1-2-3joom, you have 9-8-8 error, 1-9-9-2 warning
           

场景3:计算一段字符串内数字的和

这种场景下只用一个while会进入死循环,因此需要结合g来使用:

#!/usr/bin/perl 

my $str = "hello 123joom, you have 988 error, 1992 warning";

$_ = $str;
while(/\d+/g){
	print "get $& \n";
}
           

打印结果:

get 123 
get 988 
get 1992 
           

上面那个纯粹是刚开始写的时候就这么学的,更简单的写法是下面这样:

#!/usr/bin/perl 

my $str = "hello 123joom, you have 988 error, 1992 warning";

while($str =~ /\d+/g){
	print "get $& \n";
}
           

上面这段代码的一个小瑕疵是打印不太便捷,并不是很直观的可视,比如我想查一下为啥我的某一个值没有匹配上打印起来就比较麻烦,因此也可以下面这种写法:

#!/usr/bin/perl 

my $str = "hello 123joom, you have 988 error, 1992 warning";
my $tmp = $str;
while($tmp =~ /\d+/g){
	$tmp = $';
	print "get $&, continue: $tmp \n";
}
           

打印结果:

get 123, continue: joom, you have 988 error, 1992 warning 
get 988, continue:  error, 1992 warning 
get 1992, continue:  warning 
           

借助$` = 匹配之前的字符串, $& = 匹配到的字符串,$'为匹配之后的字符串这个属性,可以比较直观的看到循环匹配的过程。

继续阅读