简体   繁体   中英

Regex for 6 digit int that can't be sequential or repeated digits?

I am trying to get a Regex that checks to make sure that a supplied int is 6 digits and it is not sequential nor contains all repeating digits whether in ascending or descending order. I don't really care if the regex returns a match for the non-allowed numbers, or returns a match of the original number if it is allowed.

So for example all of these numbers are what I would need to not pass validation with the regex:

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

While numbers like these would pass:

  • 044346
  • 666605
  • 042004
  • 678853

Thanks.

EDIT: Appears regex is not appropriate for this. A lot of great answers and multiple are right, so I just went with who answered first, thank you all!

Regex may not be optimal for this, but it can be done with:

^
# 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}
$

Use with /x flag or (?x) to preserve the readability. You can also use the compact form (not recommended):

^(?!(\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}$

Example usage ( 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");
        }
    }
}

Output:

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

To be honest I don't think I got what you wanted, but following code works for your cases :)

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

After several re-reading I think I got what you want :) See the following:

    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}$");

The invalid strings are so little in number that you could just do this:

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
        }

    }
}

Just as a reference as to why you should NOT do this. Here's a regex that would satisfy your requirements -- it's a mess:

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

where you must expand the (?!123456) for all 20 possible iterations of repeated digits. (20 = 10 possible starting digits * (one ascending + one descending))

You start off with the negative lookahead preventing the 20 sequential digits scenarios, grab a single digit, and then do checks that require (via a negative lookeahead) that at least one digit must be different from the first digit. If it passes this, it succeeds.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM