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

^\(.*\)\(\n\1\)\+$

2)

^\(.*\n\)\(\1\)\+

详细讲解一下:\+是代表匹配>1个,\1代表是前面的匹配,那么可以看出:
第1种方法是匹配了整个行(不包括换行符),然后加上\n\1,匹配\n\1 >1次,最后匹配到最后一个重复行行尾的换行符,从而匹配到所有重复行。
如图:

删除重复行1

第2种方法则是先匹配了整个行(包括换行符),然后匹配\1 >1次,最后匹配到所有重复行。
如图:

删除重复行2

但是实际上第二种匹配规则是有bug的,即假设最后一个重复行后面再也没有换行符的话,那么是匹配不到的,如图:
第一种方法:

删除重复行3
第二种方法:

删除重复行4

到此为止,既然查找的方法已经出来了,那么替换的方法也就有了

:%s/^\(.*\)\(\n\1\)\+$/\1/

OK,就到这里啦~~~

版权所有,转载请注明出处.http://www.vimer.cn

暂无相关产品

12则回应给“vim(gvim)正则表达式查找替换(6)-压缩(删除)重复行”

  1. niejieqiang说道:

    有这样的十几万行:
    bbllllllllll
    bbmmmmkdjk
    aaakkkkk
    aaaccccccdd
    dddd8888
    dddd9999999
    他们的特点是字符串前面有1-4个字母相同,我想把这样的行全都删除, gvim中怎么操作?(不是保留一行)
    a行,b行和d行都是不同的行, 并且这文件中估计有将近一万这样重复的行.
    十万火急, 先谢谢了. 我的邮箱 niejieqiang@gmail.com

    [回复]

    Dante 回复:

    g/\(\D\)\1\{3}/s/.*\n//g

    哈,试试~~

    [回复]

    Dante 回复:

    补充一下,你说的是字母,所以上面的那个答案是只针对a~z和A~Z的,如果也包括数字的话,用这个:
    g/\(\S\)\1\{3}/s/.*\n//g

    [回复]

  2. niejieqiang说道:

    啊,还保留了一行啊,已经 非常谢谢了。

    [回复]

    Dante 回复:

    不好意思,之前写的有bug,可能会有一些匹配行未被删除,用这个命令可以解决:

    %s/.*\(\S\)\1\{3}.*\n//gc

    [回复]

    Also 回复:

    呵呵。老兄真是乐于助人哈。不过写regex来处理有规律的字符串确实很有意思。

    [回复]

  3. 依云说道:

    其实可以用:sort的。不要同时排序的话就像这样::sor ur /^/

    [回复]

    依云 回复:

    根据文档这样做似乎不一定行,因为 :sort 不保证是稳定的。不过用 /$^/ 就可以了。

    [回复]

  4. niejieqiang说道:

    非常感谢!!!!!

    [回复]

  5. 路人甲说道:

    这个问题,我捣鼓了一天一夜,也google看到了很多方法。最后我把能用的我告诉大家
    :sort
    :g/\%(^\1$\n\)\@<=\(.*\)$/d
    上楼依云说的方法也对。不过最好先拍下序
    :sort
    :sor ur /^/
    别说说的很多方法都有很多bug,不亲自拿出几十万条数据测试根本发现不了,我用20条数据测试,基本上没种方法全是对的,但是我拿出1000条数据测试后,只有上面两种方法正常,其他的都有或多或少的没考虑到的地方,各种bug,没发上图,不能详细说明。
    希望大家能早日看到这个评论,不要像我搞了一天一夜没睡。

    [回复]

    Dante 回复:

    呃,没太理解,是说文中的方法有bug吗?

    [回复]

发表评论