我试图搜索这个特定的问题,但我得到的只是删除重复的行或删除重复的字符串,它们被分隔符分隔。
我的问题略有不同。我有一个字符串,如
"comp name1 comp name2 comp name2 comp name3"
我要删除重复的comp name2并仅返回
"comp name1 comp name2 comp name3"
它们不是连续的重复单词,而是连续的重复子串。有没有办法用正则表达式解决这个问题?
答案 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";
可能很脏,但应该跑得更快。