《vim(gvim)正则表达式查找替换》是个比较久的系列了,这次因为博友niejieqiang的一个问题,所以决定继续在写一篇,而主题就是将正则表达式查找替换与vim脚本结合。
其实这种方法在之前的文章中也出现过如:
vim(gvim)正则表达式查找替换(4)-生成连续数字或行号

就是一种方式。

OK,回到正题,我们来看一下博友niejieqiang的问题:

根据之前vim(gvim)正则表达式查找替换(5)-压缩(删除)重复行中的经验,肯定需要先匹配首字母相等的两行,即:

但是这样只是把首字母相等的两行进行了折叠,如果出现了多行,那么就要执行多次。那么怎么让他自动执行多次呢?正则表达式本身应该是没有办法了,就该我们的vim脚本上台大显身手啦。
代码如下:

对于search函数的解释可以通过如下命令获取:

最终的运行结果如下:

看似很完美啦,但是结果niejieqiang发现了另一个问题,当输入为:

时,输出的结果如下:

大家应该已经看出来了,ejj中的e没了,并且和”eldv 真的”折成了同一行,问题出在哪里呢?
我们来仔细看一下:

由于*和+都是贪婪匹配,所以很难保证\1和\2的值分别是多少,比如对

来说,可以拆成”eldv”和” 真的”,也可以拆成”e”和”ldv 真的”。
OK,问题找到了,解决方案也就有了,我们只要在两个匹配中间加一个空格,即:

就完美解决啦。
最终的方案如下:

对刚才有问题的输入运行命令,输入如下:

OK,就是这样,如果大家对贪婪匹配这里有更好的解决方案,欢迎指出~

使用Vim(gvim)实现复杂的查找替换的一个例子

今天老婆在整理文档的时候希望能快捷的排版某些格式,无奈发现word并不能满足要求,所以就让我用Vim试一下。 问题如下: 1 加州大学伯克利分校 University of...

阅读全文

vim(gvim)正则表达式查找替换(6)-压缩(删除)重复行

之前有用正则表达式写过一个重复两行压缩成一行的命令,今天我们来看一个讲重复多行压缩成一行的命令。 首先,我们先考虑怎么查出多个重复行。 有两种方法,...

阅读全文

string替换所有指定字符串(C++)

C++的string提供了replace方法来实现字符串的替换,但是对于将字符串中某个字符串全部替换这个功能,string并没有实现,我们今天来做的就是这件事。 首先明白...

阅读全文

11则回应给“vim(gvim)正则表达式查找替换(7)-结合vim脚本”

  1. amao说道:

    这是要把郑码的win码表转换为小小永输入法的码表?要我做这种事情的话,还是会用python写个脚本。正则替换的表达式太长了,容易错,也记不住。

    [回复]

    Dante 回复:

    哈哈,确实,解决方法有很多种,挑自己最顺手的就行~~

    [回复]

    依云 回复:

    看来我的AWK大法应该回复到这里的 :-)

    我觊觎awk/sed已很久,但一直没有练手的机会呢。这个链接挺好的,再在这里写一遍吧 http://www.linux.gov.cn/shell/awk.htm

    [回复]

    amao 回复:

    awk做这件事情也不错,只是用的少,记不住。

    [回复]

  2. khb_gl说道:

    awk ‘{xxx[$1]=xxx[$1]” “$2} END{for(i in xxx) {print i,xxx[i]} }’ yyy

    [回复]

    依云 回复:

    感觉是抄的我的 :-P 不过不对 xxx[$1] 作判断的话,开头会多出个空格吧?
    http://www.vimer.cn/留言#comment-3968

    [回复]

  3. niejieqiang说道:

    哈哈, 没想到博主还记成文章了,那时还不知道脚本语言是什么东西,现在会一点perl了,发现这种事还是脚本靠譜:

    #!perl -w
    use strict;

    while(){
    chomp;
    my ($en,@others) = split;
    push @{$h{$en}} = @others;
    }

    for( keys %h ){
    print $_,” “;
    print join” “,@{$h{$_}};
    print “\n”;
    }

    [回复]

  4. niejieqiang说道:

    这留言板要改一下才行

    [回复]

  5. niejieqiang说道:

    试试perl语法

    [回复]

  6. tcx说道:

    请教下要是想让let i=1|g/1/s//=i/|let i=i+1里边的i以十六进制出现怎么办?谢谢

    [回复]

  7. tcx说道:

    也就是想要010203。。。090a0b。。。feff这样的效果,不是十进制的怎么办?

    [回复]

发表评论