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.