四种环视匹配
0x00 refer
0x01 detail
肯定顺序环视(?=...) positive lookahead (中文也有翻译成:后向界定)
否定顺序环视(?!...) negtive lookahead (中文也有翻译成:后向非界定)
肯定逆序环视(?<=...) positive lookbehind (中文也有翻译成:前向界定)
否定逆序环视(?<!...) negtive lookbehind (中文也有翻译成:前向非界定)
从上看出:
是 =
不是 !
在用正则表达式匹配时将待匹配的字符串变量看作是有隐藏位置的字符串,也即将abcd看作|a|b|c|d|,其中|表示一个隐藏位置. 如果正则表达式中没有上面4种用法则不考虑隐藏的位置,如果有4种任意一种则要考虑隐藏位置,以上4种在匹配时匹配的结果为 这些隐藏的位置(只匹配位置,不匹配字符).
0x02 example
a.前面没有form后面有action
使用(?:\n)不捕获匹配\n
替换(?:\n),使用(?<=\n)前向界定和(?=\n)后向界定匹配\n
上图共使用了(?<=)
,(?!=)
,(?=)
,没有用到(?<!)
为了用到(?<!)
,具体如下图
上图共使用了(?<=)
,(?<!)
,(?!)
,(?=)
b.前面有form后面没有action
上图共使用了(?<=)
,(?!)
,(?=)
,没有用到(?<!)
为了用到(?<!)
,具体如下图
上图共使用了(?<=)
,(?<!)
,(?!)
,(?=)
0x03 vim中的环视匹配
注意
1.其中上图的倒数第2个应该是:`...\@<!`
2.匹配时是正常匹配,不是\v(very magic)模式匹配
0x04 attention
1.为了匹配到一个字符串变量中没有form,可以有4种方法:
a).(?<!form)
对应的(.(?<!form))*
b)(?<!form).
对应的((?<!form).)*
c).(?!form)
对应的(.(?!form))*
d)(?!form).
对应的((?!form).)*
其中.在()前[.()
]或.在()后[().
]最终的效果一样,但是对于正则引擎来说,匹配的顺序不同,.()
是先匹配字符再匹配隐藏
的位置,().
是先匹配隐藏的位置再匹配字符
2.四种环视匹配(...)
匹配的结果是一个隐藏的位置,是一个位置,不是多个位置,也不是字符
3."ifconfig | ack '(?<=inet )(.*)(?= netmask)' -o"
可得到ip地址
echo lllnihaolllnihaoxxxnihao666 | ack -o '(?<=x)(?=n)nihao.*'
其中的(?<=x)(?=n)
两个紧挨的环视匹配得到的是一个
隐藏的位置,因为环视匹配不会匹配到字符(不捕获),于是第1个环视匹配得到1个位置后由于无法前进字符串,所以第2个环视匹配
得到的依然是相同的位置处,同理,多个紧挨的环视匹配得到的是相同的位置,说明多个环视匹配紧挨时,匹配结果与各个环视匹配
表达式的先后顺序无关