preg_match / php风格正则表达式找到重复的字母数字字符,逗号分隔?

时间:2012-04-20 01:55:10

标签: regex preg-match preg-match-all

我正在试图找出一个preg_match / php风格的正则表达式来查找重复的字母数字字符组(任意长度),用逗号分隔?

所以如果我有字符串“c,b,a,xz,x,b,a,c,xz,x,x,b,a”

将返回重复两个以上值的第一系列字母。我想我需要做一个递归的反向引用,可能就像

<?php
    // lines removed for simplicity
    // test string = "c,b,a,xz,x,b,a,c,xz,x,x,b,a"
    $haystack = "c,b,a,xz,x,b,a,c,xz,x,x,b,a";
    $answer = preg_match('/([A-z]{2,*}[\s]{1})([A-z \s]*)[\1]*/', $haystack );

    echo $answer; // print the first occurrence of the repeating series of two or more
?>

我只需找到并回显出第一次出现两个或多个值的重复序列。有没有办法递归地使用反向引用,或者更好的方法?

编辑:删除了代码呕吐。

2 个答案:

答案 0 :(得分:1)

'/\b(\w+,\w+),(?:.*,)?\1\b/'应该有效。它匹配两个项目的任何序列,任何数量的其他东西,然后再次相同的序列。

Catch是,由于正则表达式如何工作,它可能会找到具有重复的第一个序列,而不是具有第一个重复的序列。 (最早开始的匹配获胜。)例如,如果您有'a,b,c,d,c,d,a,b,c',则$matches[1]可能是'a,b',即使'c,d'之前匹配也是如此。

要查找第一个副本,您必须能够匹配它并在后面的断言中对其进行反向引用。如果这是合法的(我怀疑它是),它必须是固定的宽度才能让PHP发生。

修改 虽然,现在我考虑一下......如果你颠倒字符串然后使用'/.*\b(\w+,\w+),(?:.*?,)??\1\b/',它可能会起作用。那个围绕我提到的约束跳舞;如果字符串被反转,则副本会在原始文件之前出现,所以现在我们可以匹配副本,然后“稍后”引用它。

表达式开头的.*尽可能多地抓取,因此匹配将从反向字符串的末尾开始(因此,接近开头原始字符串)尽可能。额外的?使它们相应的位变得懒惰,所以它们尽可能地匹配。当然,一旦你在反向字符串中找到匹配项,你就需要反转它以获得原始字符串中的匹配。

当然,在UTF-8出现的情况下,这可能会打破一切。 (然后,大多数正则表达式会。)如果您只是处理ASCII,它应该可以工作。

答案 1 :(得分:1)

不是PHP专家,但我认为你可以使用这个正则表达式 在while循环中~\b([a-zA-Z0-9]{2,})\b(?=.*\b\1\b)~

在正文中,你可以在哈希数组中跟踪结果(如果php有),
打印出独特的系列和位置。捕获缓冲区1具有该系列。