Chinaunix首页 | 论坛 | 博客
  • 博客访问: 70690
  • 博文数量: 22
  • 博客积分: 141
  • 博客等级: 民兵
  • 技术积分: 140
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-28 09:31
文章分类

全部博文(22)

文章存档

2012年(13)

2011年(9)

分类:

2012-06-26 16:23:09

原文地址:sed之正则的贪婪匹配 作者:zooyo

文本:
/experience/hcj/A420103WBXZ073000021101280013801
/Cat34445/A2_Further_Maths/56/C420103WBPX010100041104200202329
/Deleted/A1_332/35/B420103WBPX010100041104200202329
/Actor/A2_334/11/A420103WBPX010100041104200202329
/Booting/A3335/32/A420103WBPX01010004110420020232

每行中存在若干个"/A" "/B" "/C" ,只替换最后一个匹配的为制表符:
/experience/hcj 420103WBXZ073000021101280013801
/Cat34445/A2_Further_Maths/56   420103WBPX010100041104200202329
/Deleted/A1_332/35      420103WBPX010100041104200202329
/Actor/A2_334/11        420103WBPX010100041104200202329
/Booting/A3335/32       420103WBPX01010004110420020232



  1. sed 's#\(.*\)/[ABC]#\1\t#' file
[解析]
这就是利用了正则的贪婪匹配,标记出 \(.*\)内容本身也包含了所有字符,那么它会一直匹配到最后一个出现的字样。简单的例子:
  1. echo "a 1 c 1 d 1 e 1"|sed 's/\(.*\)1/\1Hello/'
  2. a 1 c 1 d 1 e Hello
同样会是把最后一个1替换成Hello,那么这样呢:
  1. echo "a 1 c 1 d 1 e 1"|sed 's/\(.*\)1 /\1Hello /'
  2. a 1 c 1 d Hello e 1
因为在匹配1时标记后面多了一个空格,那么最后一个1后面是没有空格的,正则就会匹配到最后一个1后面还跟有空格的那个1,所以就是倒数第2个1了。

我们再看一个例子,如何充分的利用正则的贪婪性:
  1. # echo "123:456:789" | sed 's/.*://'
  2. 789
  3. # echo "123:456:789" | sed 's/:.*//'
  4. 123
第一个替换中 .* 是包含所有的字符,它会贪婪的匹配到最后一个:之前的所有字符,那么替换成空,自然会留下了789,第二个替换道理一样,所以剩下了123。那我们要获得第一个冒号后的内容,例如 456:789 呢?
  1. echo "123:456:789"|sed 's/[^:]*:\(.*\)/\1/'
  2. 456:789
把非冒号的内容和第一个冒号排除掉,剩下的做标记,就可以取出剩下的内容,但是这里还有一个问题,比如说分割符不是一个字符,而是一个字符串呢?比如 123A1A456A1A789 ,以A1A为分割符,我们将无法再使用[^A1A]这样写法,还记得shell的替换吗,这里就用到它了:
  1. $ i=123A1A456A1A789
  2. $ echo ${i#*A1A}
  3. 456A1A789
阅读(1790) | 评论(0) | 转发(0) |
0

上一篇:sed之大小写转换

下一篇:没有了

给主人留下些什么吧!~~