Perl正则表达式删除字符串中的重复连续子串

时间:2011-04-05 03:16:39

标签: regex perl substring

我试图搜索这个特定的问题,但我得到的只是删除重复的行或删除重复的字符串,它们被分隔符分隔。

我的问题略有不同。我有一个字符串,如

    "comp name1 comp name2 comp name2 comp name3" 

我要删除重复的comp name2并仅返回

    "comp name1 comp name2 comp name3" 

它们不是连续的重复单词,而是连续的重复子串。有没有办法用正则表达式解决这个问题?

5 个答案:

答案 0 :(得分:7)

s/(.*)\1/$1/g

请注意,此正则表达式的运行时间是字符串长度的二次方。

答案 1 :(得分:3)

这对我有用(MacOS X 10.6.7,Perl 5.13.4):

use strict;
use warnings;

my $input = "comp name1 comp name2 comp name2 comp name3" ;
my $output = "comp name1 comp name2 comp name3" ;

my $result = $input;
$result =~ s/(.*)\1/$1/g;

print "In:   <<$input>>\n";
print "Want: <<$output>>\n";
print "Got:  <<$result>>\n";

关键点是匹配中的'\ 1'。

答案 2 :(得分:2)

为避免在中删除中的重复字符(例如comm1 - &gt; com1)括号。*在正则表达式中使用\ b。

s/(\b.*\b)\1/$1/g

答案 3 :(得分:1)

我从不使用支持此功能的语言,但因为您使用的是Perl ...

转到此处..和see this section ....

有用示例:检查双字

编辑文本时,加倍的单词如“the”容易进入。在文本编辑器中使用正则表达式\ b(\ w +)\ s + \ 1 \ b,您可以轻松找到它们。要删除第二个单词,只需键入\ 1作为替换文本,然后单击“替换”按钮。

答案 4 :(得分:1)

如果你需要在线性时间内运行的东西,你可以split字符串并遍历列表:

#!/usr/bin/perl                                                                                                                                                                                       

use strict;
use warnings;

my $str = "comp name1 comp name2 comp name2 comp name3";
my @elems = split("\\s", $str);
my $prevComp;
my $prevFlag = -1;
foreach my $elemIdx (0..(scalar @elems - 1)) {
    if ($elemIdx % 2 == 1) {
        if (defined $prevComp) {
            if ($prevComp ne $elems[$elemIdx]) {
                print " $elems[$elemIdx]";
                $prevFlag = 0;
            }
            else {
                $prevFlag = 1;
            }
        }
        else {
            print " $elems[$elemIdx]";
        }
        $prevComp = $elems[$elemIdx];
    }
    elsif ($prevFlag == -1) {
        print "$elems[$elemIdx]";
        $prevFlag = 0;
    }
    elsif ($prevFlag == 0) {
        print " $elems[$elemIdx]";
    }
}
print "\n";

可能很脏,但应该跑得更快。