三剑客grep命令之Perl零宽断言


1.1 目的

(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配singdanc

(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading

零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。

(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp(?<![a-z])\d{7}匹配前面不是小写字母的七位数字。

取一个IP

[root@oldboyedu-37 ~]# ifconfig eth0 |grep -Po "[\d.]+(?=  Bcast)"
10.0.0.200

1.2 前言

零宽断言实质:匹配文本里面的位置。

为了便于大家理解,这里使用英文配合中文的方式讲解。英文才是本质。

1.3 零宽断言分类: lookaround

零宽断言叫 zero-length assertions,也叫 lookaround(这个更容易理解)。

包括:lookahead(向前看,零宽度正预测先行断言),lookbehind(向后看,零宽度正回顾后

发断言)

1.4 详细说明

1.4.1 lookahead 向前看,先行断言)

 

                                                                                  blob.png

blob.png

解释
[root@oldboyedu-37 ~]# echo "by oldboy linux" |grep  "(?=oldboy)old"
[root@oldboyedu-37 ~]# echo "by oldboy linux" |grep -P "(?=oldboy)old"
by oldboy linux
[root@oldboyedu-37 ~]# echo "by oldboy linux" |grep -Po "(?=oldboy)old"
Old

1.4.2 lookbehind (向后看,后发断言)

从右到左对文本进行匹配,判断是否符合 exp 表达式

名字

表达式

如果子表达式成功则

positive   lookbehind

(零宽度正预测先行断言)

(?<=subexp)

如果匹配到左边则成功

negative   lookbehind

零宽度负预测先行断言)

(?<!subexp)

如果没有匹配到左边则成功

注:成功就是找到对应的位置

blob.png

演示


[root@oldboyedu-37 ~]# echo "by oldboy linux" |grep -P "(?<=old)boy"
by oldboy linux
[root@oldboyedu-37 ~]# echo "by oldboy linux" |grep -Po "(?<=old)boy"
Boy


1.5 lookaheadlookbehind区别

blob.png

如图所示lookahead匹配的位置是在subexp之前,lookbehind匹配的位置是在subexp之后

1.6 perl常用的转义字符

转义字符

含义

\b

单词的边界

\w

表示[a-Za-z0-9]中任意一个字符

\W

表示\w[a-Za-z0-9]中任意一个字符

\d

[0-9]中的任意一个字符

\D

不在[0-9]中的任意一个字符

1.7 测试演练:取IP

[root@oldboyedu-37 ~]# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:0C:29:10:B5:69 
          inet addr:10.0.0.200  Bcast:10.0.0.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe10:b569/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:117881 errors:0 dropped:0 overruns:0 frame:0
          TX packets:75570 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:39427093 (37.6 MiB)  TX bytes:10123249 (9.6 MiB)

1.7.1 方法一:使用positive lookahead(正常先前看,零宽度正预测先行断言)


[root@oldboyedu-37 ~]# ifconfig eth0 |grep -Po "[\d.]+(?=  B)"
10.0.0.200
[root@oldboyedu-37 ~]# ifconfig eth0 |grep -Po "[0-9.]+(?=  B)"
10.0.0.200
解释:
1 . 这里使用lookahead的时候要注意,Bcast前面有两个空格,匹配要注意
2  \d  和 [0-9] 都是取数字0-到之间任意一个数字


1.7.2 方法二:使用positive lookbehind(正常向后看,零宽度正回顾后发断言)


[root@oldboyedu-37 ~]# ifconfig eth0 |grep -Po "(?<=\baddr:)[0-9.]+"
10.0.0.200
[root@oldboyedu-37 ~]# ifconfig eth0 |grep -Po "(?<=\baddr:)[\d.]+"
10.0.0.200


1.7.3 方法三:使用零度负预测先断言


[root@oldboyedu-37 ~]# ifconfig eth0 |grep -Po 'addr:[\d\.]+(?![\d\.])'
addr:10.0.0.200
Ø  但是还有去掉“addr:”还是需要使用lookbehind(先后看,零宽度正回顾后发断言)
[root@oldboyedu-37 ~]# ifconfig eth0 |grep -Po '(?<=addr:)[\d\.]+(?![\d\.])'
10.0.0.200


1.7.4 方法四:使用零宽度负向回顾后发断言

[root@oldboyedu-37 ~]# ifconfig eth0 |grep -Po '(?<![\d\.])[\d\.]+(?)  B'
10.0.0.200  B
Ø  但是后面的去除需要使用零宽度正预测先行断言
[root@oldboyedu-37 ~]# ifconfig eth0 |grep -oP '(?<![\d\.])[\d\.]+(?)(?=  Bca)'
10.0.0.200


打赏 支付宝打赏 微信打赏

最后编辑于:2017/06/18作者: 富华运维空间

相关推荐

发表评论

动态鼠标蜘蛛网特效