2009-10-15 116 views
16

不使用任何编程语言。只使用正则表达式。可能吗?查找重复行并使用正则表达式删除替换功能

例如输入>>

11 
22 
22 <-must remove 
33 
44 
44 <-must remove 
55 

输出>>

11 
22 
33 
44 
55 
+7

正则表达式是由一些程序(SED,Perl,Python和JAVA,东西)执行。 “不使用任何编程语言”没有任何意义。什么程序运行正则表达式? – 2009-10-15 16:08:58

+0

是的,除了S.Lott所说的,你必须更好地说明“删除”是什么意思。删除所有重复行吗?或删除所有,但一个?如果后者,你想保留哪一个,第一个还是最后一个?或者顺序无关紧要? – Davide 2009-10-15 16:37:05

+0

最后,应该一次运行,还是允许多次传球? – Davide 2009-10-15 16:37:50

回答

42

Regular-expressions.info对Deleting Duplicate Lines From a File

页这基本上可以归结为寻找这个oneliner:

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

...并替换为\1
注:点必须不匹配换行符

说明:

caret将只在一行的开始匹配。所以正则表达式引擎只会尝试匹配那里的正则表达式的其余部分。 dotstar组合只需匹配整条线,无论其内容如何。括号将匹配的行存储到第一个反向引用中。

接下来我们将匹配行分隔符。我把question mark纳入\r?\n,使这个正则表达式可以同时使用Windows(\r\n)和UNIX(\n)文本文件。所以直到这一点,我们匹配一条线和下面的换行符。

现在我们需要检查这个组合是否跟着同一行的副本。我们只需要\1。这是我们匹配的第一个反向引用。反向引用将匹配相同的文本。

如果反向引用无法匹配,则会丢弃正则表达式匹配和反向引用,并且正则表达式引擎会在下一行的开始处再次尝试。如果反向引用成功,则正则表达式中的plus symbol将尝试匹配该行的其他副本。最后,dollar symbol强制regex引擎检查反向引用所匹配的文本是否为完整行。我们已经知道反向引用匹配的文本前面有一个换行符(匹配\ r?\ n)。因此,我们现在检查它是否也跟着一个换行符,或者它是否在使用dollar sign的文件末尾。

整个比赛变成line\nline(或line\nline\nline等)。因为我们正在进行搜索和替换,所以它们之间的行,重复项和换行符都将从文件中删除。因为我们希望保持原来的路线,而不是重复,我们使用\1作为替换文本把原线回。

3

见我的更多信息的要求,我回答的容易现在方式

  1. 如果顺序并不重要,只是一个

    排序-u

    会做的伎俩

  2. 如果订单没有问题,但你不介意再可以使用:

    %s/\(。* \)\(\ _。* \)\(\ 1 \)/ \ 2 \ 1/g

    保存最后一次出现,或

    %S/\(。* \)\(\ _。* \)\(\ 1 \)/ \ 1 \ 2 /克

    保存第一次出现。

如果你确实想重新运行多次通行证,那就更难了,所以在我们开始工作之前,请在问题中这么说!

编辑:在您的编辑你不是很清楚,但它看起来像你想只是一个单一的通重复相邻的线拆除!那么,这很容易!

简单:

/(.*)\1*/\1/ 

(在vim /\(.*\)\1*/\1/),即寻找(.*)\1*,并与刚刚\1取代它会做的伎俩

+0

'(。*)\ 1 *'与重复行不匹配,因为正则表达式中没有任何内容与行和重复行之间的换行符匹配。 – 2010-02-27 10:24:07

3

在使用RegexBuddy,你可以做到这一点,如下所示:

  1. 在库选项卡上,如果默认情况下未加载,则加载RegexBuddy.rbl库。
  2. 在查找框中输入“duplicate”
  3. 单击使用按钮加载“删除重复行”正则表达式。
  4. 在GREP选项卡,指定要从删除重复的文件的文件夹和文件掩码。
  5. 在GREP按钮的下拉菜单中选择执行。

如果您只对一个文件进行此操作,则可以使用“测试”选项卡代替“GREP”选项卡。在“测试”选项卡上加载文件,然后单击主工具栏中的“替换”按钮。