vim(gvim)正则表达式查找替换(7)-结合vim脚本
Published on 十一月 30, 2010
《vim(gvim)正则表达式查找替换》是个比较久的系列了,这次因为博友niejieqiang的一个问题,所以决定继续在写一篇,而主题就是将正则表达式查找替换与vim脚本结合。
其实这种方法在之前的文章中也出现过如:
vim(gvim)正则表达式查找替换(4)-生成连续数字或行号中
1 | let i=1|g/1/s//\=i/|let i=i+1 |
就是一种方式。
OK,回到正题,我们来看一下博友niejieqiang的问题:
A格式如下: nrk 你 nrk 侚 …. sobb 论坛 sobb 交款 sobb 文坛 … ejj 茴 ejj 莒 需要转换成B格式: nrk 你 侚 sobb 论坛 交款 文坛 ejj 茴 莒
根据之前vim(gvim)正则表达式查找替换(5)-压缩(删除)重复行中的经验,肯定需要先匹配首字母相等的两行,即:
1 | %s/^\(\S\+\)\(.*\)\n\1\(.*\)$/\1\2\3/g |
但是这样只是把首字母相等的两行进行了折叠,如果出现了多行,那么就要执行多次。那么怎么让他自动执行多次呢?正则表达式本身应该是没有办法了,就该我们的vim脚本上台大显身手啦。
代码如下:
1 | while search('^\(\S\+\)\(.*\)\n\1\(.*\)',"w")>0 | %s/^\(\S\+\)\(.*\)\n\1\(.*\)$/\1\2\3/g | endwhile |
对于search函数的解释可以通过如下命令获取:
1 | :h search |
最终的运行结果如下:
nrk 你 侚 sobb 论坛 交款 文坛 ejj 茴 莒
看似很完美啦,但是结果niejieqiang发现了另一个问题,当输入为:
sobb 论坛 sobb 交款 sobb 文坛 eldv 真的 ejj 茴 ejj 莒
时,输出的结果如下:
sobb 论坛 交款 文坛 eldv 真的jj 茴jj 莒
大家应该已经看出来了,ejj中的e没了,并且和"eldv 真的"折成了同一行,问题出在哪里呢?
我们来仔细看一下:
1 | ^\(\S\+\)\(.*\) |
由于*和+都是贪婪匹配,所以很难保证\1和\2的值分别是多少,比如对
eldv 真的
来说,可以拆成"eldv"和" 真的",也可以拆成"e"和"ldv 真的"。
OK,问题找到了,解决方案也就有了,我们只要在两个匹配中间加一个空格,即:
1 | \(\S\+\)\(\s.*\) |
就完美解决啦。
最终的方案如下:
1 | while search('^\(\S\+\)\(\s.*\)\n\1\(\s.*\)','w')>0 | %s/^\(\S\+\)\(\s.*\)\n\1\(\s.*\)$/\1\2\3/g | endwhile |
对刚才有问题的输入运行命令,输入如下:
sobb 论坛 交款 文坛 eldv 真的 ejj 茴 莒
OK,就是这样,如果大家对贪婪匹配这里有更好的解决方案,欢迎指出~
原创文章,版权所有。转载请注明:转载自Vimer的程序世界 [ http://www.vimer.cn ]
本文链接地址: http://www.vimer.cn/?p=1810
这是要把郑码的win码表转换为小小永输入法的码表?要我做这种事情的话,还是会用python写个脚本。正则替换的表达式太长了,容易错,也记不住。
[回复]
Dante 回复:
十一月 30th, 2010 at 6:41 下午
哈哈,确实,解决方法有很多种,挑自己最顺手的就行~~
[回复]
依云 回复:
十一月 30th, 2010 at 7:00 下午
看来我的AWK大法应该回复到这里的
我觊觎awk/sed已很久,但一直没有练手的机会呢。这个链接挺好的,再在这里写一遍吧 http://www.linux.gov.cn/shell/awk.htm
[回复]
amao 回复:
十一月 30th, 2010 at 7:03 下午
awk做这件事情也不错,只是用的少,记不住。
[回复]
awk ‘{xxx[$1]=xxx[$1]” “$2} END{for(i in xxx) {print i,xxx[i]} }’ yyy
[回复]
依云 回复:
十一月 30th, 2010 at 10:11 下午
感觉是抄的我的
不过不对 xxx[$1] 作判断的话,开头会多出个空格吧?
http://www.vimer.cn/留言#comment-3968
[回复]