匹配不在Regex中重复字符的字符串

时间:2011-09-14 17:11:14

标签: php regex

我是Regex的新手。我要做的是检查数值是否重复数字。它们可以在字符串中的任何位置:例如。

123456789 -> would return true
987612345 -> true

但:

122345678 -> would return false because it uses two times the number 2.
182345688 -> false

是否可以在PHP中使用Regex执行此操作?

5 个答案:

答案 0 :(得分:5)

如果您不想使用具有大量递归回溯的正则表达式:

$duplicates = count(count_chars($test, 1)) < strlen($test);

Demo


修改

如果您想使用正则表达式,只需找到一个副本然后退出:

$duplicates = preg_match('/(.).*\1/', $test);

Demo

答案 1 :(得分:2)

重新出现的字符将返回1,例如:

$match = preg_match_all('/(.).*\1/', '121345678', $arr, PREG_PATTERN_ORDER);

其他人将返回0,例如:

$match = preg_match_all('/(.).*\1/', '12345678', $arr, PREG_PATTERN_ORDER);

因此(我将其命名为clean为“非重复”):

$clean = $match == 0;

编辑:
也许是为了解释:\1是对第一个(在这种情况下)只有一对() - s的反向引用。所以当找到一个“在那次事件发生之前就已存在”的字符时,这个正则表达式就匹配了。

答案 2 :(得分:0)

如果它们可以在你的字符串中的任何地方,那就不容易了。我认为使用regexp在某种程度上是可能的。但我建议采取另一种方式:

  • 将字符串中的单个字符提取为字符数组
  • 对数组进行排序
  • 检查两个相邻字符是否相同

或任何等效技术。但我认为这个问题有点太复杂了,无法通过正常的优雅方式解决。

答案 3 :(得分:0)

至于正则表达式我不是百分百肯定,但你可以这样做:

function hasRepeatingNumbers($number) {
    $numberArray = array_unique(str_split($number));
    if(count($numberArray) != strlen($number)) {
        return true;
    else
        return false;
}

在上面的示例中,我们删除了任何重复的数字并比较每个变量的长度。如果他们是不同的,那是因为我们删除了重复的数字。

然后你应该只需要:

if(hasRepeatingNumbers('123456789'))
    echo "No repeating numbers";
else
    echo "There are repeating numbers";

这应该就像。

答案 4 :(得分:0)

/(\d)(?=.*\1)/

仅在找到第一个重复时查找数字,匹配/退出 警告!,这可能很慢。

我想这会做到这一点 if ( preg_match( '/(\d)(?=.*\1)/', "your string", $match) ) ..

如果数字0-9是唯一且字符串为
,则此方法可能会导致问题 很长。理论上,它会检查绳子长度的10倍。

另一方面,如果您的数字超过10位,则至少有一个副本 因此,在single pass中,提取前11位数字。然后你可以左 循环遍历(最多11位)数组元素,或者如果PHP那样使用散列。
这是最快的方法,它可能是一个冗长的正则表达式(11个捕获缓冲区),但PCRE不能执行可变数量的捕获缓冲区。

Perl中的示例(使用哈希):

$_ = '12asasdf3456789 4 0 asdf 3';

my @found = /
 ^
  [^\d]*
  (\d) [^\d]*(\d?)[^\d]*(\d?)[^\d]*(\d?)[^\d]*(\d?)[^\d]*
  (\d?)[^\d]*(\d?)[^\d]*(\d?)[^\d]*(\d?)[^\d]*(\d?)[^\d]*
  (\d?)
/x;

for (@found) {
   if ($seen{$_}++) {
      print "Found a duplicate: '$_'\n";
      last;
   }
}

输出:
Found a duplicate: '4'