不使用任何编程语言。只使用正则表达式。可能吗?查找重复行并使用正则表达式删除替换功能
例如输入>>
11
22
22 <-must remove
33
44
44 <-must remove
55
输出>>
11
22
33
44
55
不使用任何编程语言。只使用正则表达式。可能吗?查找重复行并使用正则表达式删除替换功能
例如输入>>
11
22
22 <-must remove
33
44
44 <-must remove
55
输出>>
11
22
33
44
55
Regular-expressions.info对Deleting Duplicate Lines From a File
页这基本上可以归结为寻找这个oneliner:
^(.*)(\r?\n\1)+$
...并替换为\1
。
注:点必须不匹配换行符
说明:
的caret将只在一行的开始匹配。所以正则表达式引擎只会尝试匹配那里的正则表达式的其余部分。 dot和star组合只需匹配整条线,无论其内容如何。括号将匹配的行存储到第一个反向引用中。
接下来我们将匹配行分隔符。我把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
作为替换文本把原线回。
见我的更多信息的要求,我回答的容易现在方式。
如果顺序并不重要,只是一个
排序-u
会做的伎俩
如果订单没有问题,但你不介意再可以使用:
%s/\(。* \)\(\ _。* \)\(\ 1 \)/ \ 2 \ 1/g
保存最后一次出现,或
%S/\(。* \)\(\ _。* \)\(\ 1 \)/ \ 1 \ 2 /克
保存第一次出现。
如果你确实想重新运行多次通行证,那就更难了,所以在我们开始工作之前,请在问题中这么说!
编辑:在您的编辑你不是很清楚,但它看起来像你想只是一个单一的通重复相邻的线拆除!那么,这很容易!
简单:
/(.*)\1*/\1/
(在vim /\(.*\)\1*/\1/
),即寻找(.*)\1*
,并与刚刚\1
取代它会做的伎俩
'(。*)\ 1 *'与重复行不匹配,因为正则表达式中没有任何内容与行和重复行之间的换行符匹配。 – 2010-02-27 10:24:07
在使用RegexBuddy,你可以做到这一点,如下所示:
如果您只对一个文件进行此操作,则可以使用“测试”选项卡代替“GREP”选项卡。在“测试”选项卡上加载文件,然后单击主工具栏中的“替换”按钮。
正则表达式是由一些程序(SED,Perl,Python和JAVA,东西)执行。 “不使用任何编程语言”没有任何意义。什么程序运行正则表达式? – 2009-10-15 16:08:58
是的,除了S.Lott所说的,你必须更好地说明“删除”是什么意思。删除所有重复行吗?或删除所有,但一个?如果后者,你想保留哪一个,第一个还是最后一个?或者顺序无关紧要? – Davide 2009-10-15 16:37:05
最后,应该一次运行,还是允许多次传球? – Davide 2009-10-15 16:37:50