1.1 目的
(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。
(?<=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 (向前看,先行断言)
|
解释
[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) | 如果没有匹配到左边则成功 |
注:成功就是找到对应的位置 |
演示
[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 lookahead与lookbehind区别
如图所示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
发表评论