如何找到一行中重叠的最大重复字符串

时间:2014-04-28 11:05:48

标签: regex perl

我有一系列的行,例如

my $string = "home test results results-apr-25 results-apr-251.csv";
@str = $string =~ /(\w+)\1+/i;
print "@str";

如何找到重叠的最大重复字符串,用空格分隔? 在这种情况下,我正在寻找输出:

results-apr-25

4 个答案:

答案 0 :(得分:2)

看起来你需要计算最长公共子串的String::LCSS_XS。不要尝试使用Perl-only双胞胎兄弟String::LCSS因为那个中有错误。

use strict;
use warnings;

use String::LCSS_XS;
*lcss = \&String::LCSS_XS::lcss; # Manual import of `lcss`

my $var = 'home test results results-apr-25 results-apr-251.csv';
my @words = split ' ', $var;

my $longest;
my ($first, $second);

for my $i (0 .. $#words) {
  for my $j ($i + 1 .. $#words) {
    my $lcss = lcss(@words[$i,$j]);
    unless ($longest and length $lcss <= length $longest) {
      $longest = $lcss;
      ($first, $second) = @words[$i,$j];
    }
  }
}

printf qq{Longest common substring is "%s" between "%s" and "%s"\n}, $longest, $first, $second;

<强>输出

Longest common substring is "results-apr-25" between "results-apr-25" and "results-apr-251.csv"

答案 1 :(得分:1)

my $var = "home test results results-apr-25 results-apr-251.csv";
my @str = split " ", $var;
my %h;
my $last = pop @str;

while (my $curr = pop @str ) {
        if(($curr =~/^$last/) || $last=~/^$curr/) {
                $h{length($curr)}= $curr ;
        }
        $last = $curr;
}

my $max_key = max(keys %h);
print $h{$max_key},"\n";

答案 2 :(得分:1)

如果你想在没有循环的情况下制作它,你将需要/g正则表达式修饰符。

这将为您提供所有重复的字符串:

my @str = $string =~ /(\S+)(?=\s\1)/ig;

我已将\w替换为\S(在您的示例中,\w-不匹配),并使用了前瞻:(?=\s\1)表示匹配\s\1之前的内容,而不匹配\s\1本身 - 这是确保在第一个字符串后开始下一个匹配尝试所必需的,而不是在第二个之后。

然后,只需从@str中提取最长的字符串:

my $longest = (sort { length $b <=> length $a } @str)[0];

(请注意,这是一个清晰易读但远不是找到最长值的最有效方法,但这是a different question.的主题)

答案 3 :(得分:0)

怎么样:

my $var = "home test results results-apr-25 results-apr-251.csv";
my $l = length $var;
for (my $i=int($l/2); $i; $i--) {
    if ($var =~ /(\S{$i}).*\1/) {
        say "found: $1";
        last;
    }
}

<强>输出:

found:  results-apr-25