与最长重复序列匹配的正则表达式

时间:2012-02-07 14:04:48

标签: regex text full-text-search

我希望匹配至少重复一次的最长序列

有:

T_send_ack-new_amend_pending-取消-replace_replaced_cancel_pending-取消-replace_replaced

结果应为: pending-cancel-replace_replaced

4 个答案:

答案 0 :(得分:4)

试试这个

(.+)(?=.*\1)

here on Regexr

这将匹配任何至少有一个字符的字符序列,稍后将在字符串中重复。

您需要存储您的比赛并决定哪一个比赛最长。

此解决方案需要您的正则表达式支持反向引用和前瞻。

它将匹配具有至少一个字符.+的任何字符序列,并将其存储在组1中,因为它周围有括号。下一步是正向前瞻(?=.*\1),如果捕获的序列再次出现在字符串中,则会出现这种情况。

答案 1 :(得分:2)

我不得不承认这个让我思考。很明显,使用正则表达式来解决这个问题绝对是必要的。无论如何,它在Java中是如何工作的:

public static String biggestOccurance(String input){
    Pattern p = Pattern.compile("(.+)(?=.*\\1)");
    Matcher m = p.matcher(input);

    String longestOccurence = "";
    while(m.find()){
        if(longestOccurence.length() < m.group(1).length()) longestOccurence = m.group(1);
    }
    return longestOccurence;
}

让我陷入困境的是

  

\\ 1

我知道您可以使用

引用Java中的反向引用
  

$ 1

但如果用\\ 1替换$ 1,则无效。

将不得不深入研究。

干杯,尤金。

答案 2 :(得分:2)

这是一个完成工作的perl脚本:

#!/usr/bin/perl 
use strict;
use warnings;
use 5.010;

my $s = q/T_send_ack-new_amend_pending-cancel-replace_replaced_cancel_pending-cancel-replace_replaced/;
my $max = 0;
my $seq = '';
while($s =~ /(.+)(?=.*\1)/g) {
    if(length$1 > $max) {
        $max = length $1;
        $seq = $1;
    }
}
say "longuest sequence : $seq, length = $max"

<强>输出:

longuest sequence : _pending-cancel-replace_replaced, length = 32

答案 3 :(得分:1)

使用Perl,您可以:

s='T_send_ack-new_amend_pending-cancel-replace_replaced_cancel_pending-cancel-replace_replaced'
echo $s | perl -pe 's/([^\s]+)(?=.*?\1)/\1\n/g'

给出了:

T_
send_
ac
k-
n
e
w_
a
mend
_pending-cancel-replace_replaced
_
cancel
_
p
e
n
d
in
g-
c
a
nce
l
-replace
_re
placed

然后你需要用任何语言或脚本发布它以获得最长的文本。

重复字符串的一个可能的后处理可以使用awk:

echo $s | perl -pe 's/([^\s]+)(?=.*?\1)/\1\n/g' | awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }'

打印哪些:

_pending-cancel-replace_replaced

PS:注意这里最长的字符串是_pending-cancel-replace_replaced