我有一系列的行,例如
my $string = "home test results results-apr-25 results-apr-251.csv";
@str = $string =~ /(\w+)\1+/i;
print "@str";
如何找到重叠的最大重复字符串,用空格分隔? 在这种情况下,我正在寻找输出:
results-apr-25
答案 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