6位int的正则表达式,不能是连续或重复的数字?

时间:2012-03-01 16:07:14

标签: c# .net regex

我试图得到一个正则表达式,它检查以确保提供的int是6位数,并且它不是顺序的,也不包含所有重复数字,无论是升序还是降序。我真的不在乎正则表达式是否返回非允许数字的匹配项,或者如果允许则返回原始数字的匹配项。

因此,例如,所有这些数字都是我不需要通过正则表达式进行验证的原因:

  
      
  • 123456
  •   
  • 654321
  •   
  • 069
  •   
  • 456789
  •   
  • 2435
  •   
  • 444444
  •   

虽然这些数字会通过:

  
      
  • 044346
  •   
  • 666605
  •   
  • 042004
  •   
  • 678853
  •   

感谢。

编辑:出现正则表达式不适合这个。很多很好的答案和多个是正确的,所以我只是先跟谁回答,谢谢大家!

5 个答案:

答案 0 :(得分:5)

正则表达式可能不是最佳选择,但可以通过以下方式完成:

^
# fail if...
(?!
    # repeating numbers
    (\d) \1+ $
    |
    # sequential ascending
    (?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)|9(?=0)){5} \d $
    |
    # sequential descending
    (?:0(?=9)|1(?=0)|2(?=1)|3(?=2)|4(?=3)|5(?=4)|6(?=5)|7(?=6)|8(?=7)|9(?=8)){5} \d $
)
# match any other combinations of 6 digits
\d{6}
$

/x标志或(?x)一起使用以保持可读性。 您也可以使用紧凑形式(不推荐):

^(?!(\d)\1+$|(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)|9(?=0)){5}\d$|(?:0(?=9)|1(?=0)|2(?=1)|3(?=2)|4(?=3)|5(?=4)|6(?=5)|7(?=6)|8(?=7)|9(?=8)){5}\d$)\d{6}$

示例用法(ideone):

using System;
using System.Text.RegularExpressions;

public class Test
{
    public static void Main()
    {
        string re = @"(?x)
            ^
            # fail if...
            (?!
                # repeating numbers
                (\d) \1+ $
                |
                # sequential ascending
                (?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)|9(?=0)){5} \d $
                |
                # sequential descending
                (?:0(?=9)|1(?=0)|2(?=1)|3(?=2)|4(?=3)|5(?=4)|6(?=5)|7(?=6)|8(?=7)|9(?=8)){5} \d $
            )
            # match any other combinations of 6 digits
            \d{6}
            $
        ";

        string[] numbers = { "102", "111111", "123456", "654321", "123455", "321123", "111112" };

        foreach (var str in numbers)
        {
            Console.WriteLine(str);
            Console.WriteLine(Regex.IsMatch(str, re) ? "\tMatched" : "\tFailed");
        }
    }
}

输出:

102
    Failed
111111
    Failed
123456
    Failed
654321
    Failed
123455
    Matched
321123
    Matched
111112
    Matched

答案 1 :(得分:3)

说实话,我认为我没有得到你想要的东西,但是下面的代码适用于你的情况:)

var isMatch = Regex.IsMatch(input, "^[0-9]{6}$")
                    && Regex.IsMatch(input, @"(([0-9]{1})\2+)")
                    && input.Distinct().Count() > 1;

经过多次重读后,我想我得到了你想要的东西:)请参阅以下内容:

    var isMatch = String.Join("", input.OrderBy(c => c)) != input
        &&  String.Join("", input.OrderByDescending(c => c)) != input
        && input.Distinct().Count() > 1
        && Regex.IsMatch(input, "^[0-9]{6}$");

答案 2 :(得分:2)

无效字符串数量太少,您可以这样做:

using System.Xml;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;

class Program {

    static void Main(string[] args) {

        string input = "124032";

        string[] invalid = { 
            "012345",
            "123456",
            // ...
            "000000",
            "111111",
            // ...
        };

        if (Regex.IsMatch(input, @"^\d{6}$") && !invalid.Contains(input)) {
            // ok
        }

    }
}

答案 3 :(得分:1)

作为参考,为什么你不应该这样做。这是一个满足您要求的正则表达式 - 这是一团糟:

(?!123456)(\d)(((?!\1)\d{5})|((\d)(?!\1)\d{4})|((\d){2}(?!\1)\d{3})|((\d){3}(?!\1)\d{2})|((\d){4}(?!\1)\d))

您必须展开所有20次重复数字迭代的(?!123456)。 (20 = 10个可能的起始数字*(一个上升+一个下降))

您从负向预测开始,阻止20个连续数字方案,抓取一个数字,然后执行需要(通过负lookeahead)至少一个数字必须与第一个数字不同的检查。如果它通过了,它就会成功。

答案 4 :(得分:0)

这不是一个优雅的解决方案,但有效!

/^[0]{6}|[1]{6}|[2]{6}|[3]{6}|[4]{6}|[5]{6}|[6]{6}|[7]{6}|[8]{6}|[9]{6}$/