精通正则表达式四:环视功能

来源:互联网 发布:pda软件开发工程师招聘 编辑:程序博客网 时间:2024/06/05 17:50

环视功能的介绍

环视有下面四种类型

(?=...)   肯定顺序环视,子表达式能匹配右侧的文本(?!...)   否定顺序环视,子表达式不能匹配右侧的文本(?<=...)  肯定逆序环视,子表达式能匹配左侧的文本(?<!...)  否定逆序环视,子表达式不能匹配左侧的文本

同样,先举例子:
这里写图片描述
这是一个肯定顺序环视,如果a的右侧是数字,那么就能匹配到a。

再来看一下否定顺序环视,其实根据上面就很好理解,如果a的右侧不是数字,那么就匹配a:
这里写图片描述
结果正如所预料的那样,但要注意的是,a的左侧没有字符也匹配了,所以‘(?!\d)’与‘\D’是不同的,‘\D’表达的是某个数字不是字符,但前提是要有这个字符:
这里写图片描述
逆序环视和顺序环视是类似的,只不过它匹配的是左侧的文本,这里不做过多演示,而且在RegExr上也不支持逆序环视。

环视不会占用字符

通过上面的例子,我们还可以发现,环视不会占用字符,也就是说,环视它就是看一下是不是,但并不会匹配它,也就不会占用这个字符:
这里写图片描述
可以看到,肯定环视中的‘\d’并没有匹配字符,而是后面的那个‘\d’匹配了。

应用

先来看一个简单的例子,比如我要将Toms改为Tom’s,就可以用环视来解决:

my $name = 'Toms';$name =~ s/(?<=Tom)(?=s)/'/g;

这样看来环视的作用并不是很大,因为不用环视也能完成这项工作并且也不复杂:

my $name = 'Toms';$name =~ s/(Tom)(s)/$1'$2/g;

在来看一个例子,就能体会环视的作用了,它采用的就是环视不占用字符的特点,在数值间插入逗号,比如‘12345678’变为‘12,345,678’。
逗号插入的位置有这样的特点,左边是数字,右边的数字是三的倍数,如果不用环视来匹配的话,要这样

my $num = 12345678;$num =~ s/(\d)((\d\d\d)+\b)/$1,$2/g

但这样能加入所有的逗号吗?答案是否定的,因为‘(\d\d\d)+\b’已经将后面的字符都占用了,就不会再次匹配。但它也可以完成,过要加一个while循环不断匹配,直到匹配不上为止:

while($num =~ s/(\d)((\d\d\d)+\b)/$1,$2/g){}

接下来用环视来做,

my $num = 12345678;$num =~ s/(?<=\d)(?=((\d\d\d)+$))/,/g;

因为RegExr上不支持逆序环视,所以也可以这样:

my $num = 12345678;$num =~ s/(\d)(?=((\d\d\d)+$))/$1,/g;

看看匹配结果:
这里写图片描述
正是我们所需要的将‘2’和‘5’替换为‘2,’和‘5,’。
如果要将一个文件中所有的数字都加上逗号,可以在终端用一条命令完成:

perl -p -i -e 's/(?<=\d)(?=((\d\d\d)+\b))/,/g' word.txt

虽然不用环视也能完成,但效率明显要低很多!

原创粉丝点击