grep在一个文本中查找符合条件的文本

时间:2022-09-08 22:26:14

好久没有写过正则的东西了。今天说说零宽断言,我看过网上那篇著名的《正则表达式30分钟入门》,那时应该是08年左右,我还觉得正则太难了。《编译原理及实践》中讲到了正则,但这门课程本身我就学得乱七八糟。

零宽断言的英文原文:

Zero-WidthAssertions

     看到网上的文章,我觉得零宽断言讲的还是不够详细。我觉得以下的理解或许可以简化零宽断言的概念。简而言之,零宽断言的作用就是去掉你不关心的部分内容。

举个例子:在linux系统上面获取或者本机的IP地址

ifconfig可以看到激活的网络接口的详细信息,那么肯定我们需要借助grep来过滤出IP地址了。因为服务器有多个接口,我只关心公网IP的地址,可以看到eth下面一行显示了IP地址。

ifconfig | grep eth -A 1 得到如下的结果:

eth0     Link encap:Ethernet  HWaddr 12:31:43:03:98:2C 
         inet addr:10.150.151.218 Bcast:10.150.151.255  Mask:255.255.254.0

观察到ip地址的前面是addr:这几个字符,于是再来过滤

 ifconfig | grep eth -A 1 | grep -oP'addr:[\d\.]+' 得到新的结果:

addr:10.150.151.218

这里我们使用了-o和-P选项,指定-o是因为grep默认是显示匹配的那一行,我们只关心精确匹配的部分而不是整行。至于-P表明后面的pattern是perl兼容正则表达式,因为pcre才支持零宽断言。可以看到结果中多了addr:这几个字符,这个时候该零宽断言大显身手了。不想要addr:这几个字符,那我们就去掉他。如下方式:

 ifconfig | grep eth -A 1 | grep -oP'(?<=addr:)[\d\.]+'

注意粗体部分,这个东西的英文名字我不太清楚,但有人这样翻译:零宽度正回顾后发断言,看到这个名字能不晕吗。其实我们不关心它叫什么,我们只关心它的作用。实际操作的时候,我们可以这样做,比如我想匹配addr:后面跟一个ip地址的情况(前文所言),但我只想要ip地址。那我们先来普通的过滤得到一个带addr:的结果,最后再去掉那些我们不想要的部分就可以了。至于怎么去掉,如果是去掉模式前面的部分,用(?<=xxx),如果是模式后面的部分,用(?=xxx),其中xxx就是你不想要的那些内容。不太好记住?实际上是比较一致的,左边的多了一个<,正好是向左的箭头。

至于有人又说到匹配方式的问题,个人觉得也不用太关心。我们不需要去关心正则表达式的具体实现,只要记住正则是贪心的就对了。所以以下命令得到的结果也就不奇怪了。

echo 'cooking singing' | grep -oP "[a-z]*(?=ing)"      ----------->cook sing

echo 'abcdefgabc' | grep -oP'(?<=abc).*'          -----------------> defgabc

 零宽断言的作用跟正则中的锚位置相同,比如我想要寻找以abc开头的行,很自然我们会想到^abc,同样,abc结尾的行--abc$,但我们并不关心^$本身,他只是我们匹配模式的锚点。零宽断言的作用正是如此,比如匹配abc后面跟了一个xxx,但我只要xxx不要abc,那么就是(?<=abc)xxx。所谓零宽就是宽度为0,我们要抛弃掉这样的锚点。

至于负向零宽断言,意思是说在我们的锚点周围不存在这样的匹配。还是举行首和行尾的情况,我们要寻找不是abc开头的行--^[^a][^b][^c]。这次我没有自然想到,一时还没有反应过来,所谓开头不是abc的意思就是第一个字符不是a,第二个字符不是b,第三个字符不是c,我现在还只知道前面的那种写法。这句话也可以说成是,行首后面不是abc。类似的不以abc结尾的行,[^a][^b][^c]$。那我想要找abc后面不是xxx的情况呢?这就要用到零宽断言了,因为行首在正则中默认就是一个锚点,但是你自定义的abc显然不是。与零宽断言类似,只不过把=换成!就行了,比如(?

犯了一个巨大的错误。(?

写道这里,我又想起了vim的正则,因为vim的正则确实跟perl不相同,有时候用着也犯晕。以下是对比:

http://xjzhou.wordpress.com/2010/05/22/各种工具:grep、sed、awk、vim、perl、javascript-之正则表达式语法比/

Lookahead and Lookbehind Zero-Width Assertions
Positive and Negative Lookahead
Positive and Negative Lookbehind
Lookaround Is Atomic

http://hooopo.iteye.com/blog/407062

http://www.regular-expressions.info/lookaround.html

http://www.cnblogs.com/xiehuiqi220/archive/2009/02/06/1385481.html

 http://deerchao.net/tutorials/regex/regex.htm#lookaround

 

http://hi.baidu.com/newdreamllc/item/e0daae2d3b612b0b72863e80(zz)