Regex to match 7 same digits in a number regardless of position - c#

I want to match an 8 digit number. Currently, I have the following regex but It is failing in some cases.
(\d+)\1{6}
It matches only when a number is different at the end such as 44444445 or 54444444. However, I am looking to match cases where at least 7 digits are the same regardless of their position.
It is failing in cases like
44454444
44544444
44444544
What modification is needed here?

It's probably a bad idea to use this in a performance-sensitive location, but you can use a capture reference to achieve this.
The Regex you need is as follows:
(\d)(?:.*?\1){6}
Breaking it down:
(\d) Capture group of any single digit
.*? means match any character, zero or more times, lazily
\1 means match the first capture group
We enclose that in a non-capturing group {?:
And add a quantifier {6} to match six times

You can sort the digits before matching
string input = "44444445 54444444 44454444 44544444 44444544";
string[] numbers = input.Split(' ');
foreach (var number in numbers)
{
number = String.Concat(str.OrderBy(c => c));
if (Regex.IsMatch(number, #"(\d+)\1{6}"))
// do something
}
Still not a good idea to use regex for this though

The pattern that you tried (\d+)\1{6} matches 6 of the same digits in a row. If you want to stretch the match over multiple same digits, you have to match optional digits in between.
Note that in .NET \d matches more digits than 0-9 only.
If you want to match only digits 0-9 using C# without matching other characters in between the digits:
([0-9])(?:[0-9]*?\1){6}
The pattern matches:
([0-9]) Capture group 1
(?: Non capture group
[0-9]*?\1 Match optional digits 0-9 and a backreference to group 1
){6} Close non capture group and repeat 6 times
See a .NET Regex demo
If you want to match only 8 digits, you can use a positive lookahead (?= to assert 8 digits and word boundaries \b
\b(?=\d{8}\b)[0-9]*([0-9])(?:[0-9]*?\1){6}\d*\b
See another .NET Regex demo

Related

Regex pattern infinite number of times except last one different

I'm trying to build a regex to check if a text input is valid.
The pattern is [NumberBetween1And999]['x'][NumberBetween1And999][','][White space Optional] repeated infinite times.
I need this to make an order from a string: the first number is the product id and the second number is the quantity for the product.
Examples: of good texts:
1x1
2x1,3x1
1x3, 4x1
Should not catch:
1x1,
1,1, 1x1,
9999x1
1x1,99999x1
I'm blocked there: ^(([1-9][0-9]{0,2})x([1-9][0-9]{0,2}),)*$
Thanks for helping me
You can use
^[1-9][0-9]{0,2}x[1-9][0-9]{0,2}(?:,\s*[1-9][0-9]{0,2}x[1-9][0-9]{0,2})*$
The pattern matches:
^ Start of string
[1-9][0-9]{0,2}x[1-9][0-9]{0,2} Match a digit 1-9 and 2 optional digits 0-9, then x and again the digits part
(?: Non capture group to repeat as a whole
,\s* Match a comma and optional whitespace char
[1-9][0-9]{0,2}x[1-9][0-9]{0,2} Match the same pattern as at the beginning
)* Close the non capture group and optionally repeat it to also match a single part without a comma
$ End of string
Regex demo

C# regex string that is not another string

I want to match an at least 3 letter word, preceded by any character from class [-_ :] any amount of times, that is not this specific 3 letter word string2.
Ex:
if string2="VER"
in
" ODO VER7"
matched " ODO"
or
"_::ATTPQ VER7"
matched "_::ATTPQ"
but if
" VER7"
it shoudn't match " VER"
so I thought about
Regex.Match(inputString, #"[-_:]*[A-Z]{3,}[^(VER)]", RegexOptions.IgnoreCase);
where
[-_:]* checks for any character in class, appearing 0 or more times
[A-Z] the range of letters that could form the word
{3,} the minimum amount of letters to form the word
[^(VER)] the grouping construct that shouldn't appear
I believe however that [A-Z]{3,} results in any letter at least 3 times (not what i want)
and [^(VER)] not sure what it's doing
Using [^(VER)] means a negated character class where you would match any character except ( ) V E or R
For you example data, you could match 0+ spaces or tabs (or use \s to also match a newline).
Then use a negative lookahead before matching 3 or more times A-Z to assert what is on the right is not VER.
If that is the case, match 3 or more times A-Z followed by a space and VER itself.
^[ \t]*[-_:]*(?!VER)[A-Z]{3,} VER
Regex demo
^\s*[-_:]*(?!VER)[A-Z]{3,}
This regex asserts that between the start and end of the string, there's zero or more of your characters, followed by at least 3 letters. It uses a negative lookahead to make sure that VER (or whatever you want) is not present.
Demo
This would match the preceding class characters [-_ :] of 3 or more letters/numbers
that do not start with VER (as in the samples given) :
[-_ :]+(?!VER)[^\W_]{3,}
https://regex101.com/r/wLw23I/1

Regular expression to match 1-5 symbols when start symbol letter and at least one number

I tried this expression:
/([a-z]+[0-9]+[a-z]*){1,5}$/
but it's works for every word that start with letter and contains at least one number and more then two symbol for example "re1111e" when its not supposed to, what am I doing wrong?
One possible way to write your regex uses a positive lookahead to check for a number:
/(?=[^0-9]*[0-9])[a-z][a-z0-9]{0,4}/
This pattern says to:
(?=[^0-9]*[0-9]) assert that a single digit appears somewhere
[a-z] match an initial letter character
[a-z0-9]{0,4} then match zero to four letter or number characters
In your pattern, the quantifier {1,5} apllies to the group repeating this match [a-z]+[0-9]+[a-z]* 1 - 5 times.
If I am not mistaken, you want to match [a-z] from the start followed by 4 chars from which one of them is at least 1 digit so the minimum amount of characters is 2 and the maximum is 5.
You might use:
^(?=.{2,5}$)[a-z][a-z0-9]*[0-9][a-z0-9]*$
About the pattern
^ Start of string
(?=.{2,5}$ Assert string length 2 - 5 characters
[a-z] Match a-z
[a-z0-9]* Repeat 0+ times matching a-z 0-9
[0-9] Match a digit
[a-z0-9]* Repeat 0+ times matching a-z 0-9
$ End of string
Regex demo

Regex Situation... More than one group with variable spaces

I'm new to regex but I seem to have things going my way.
https://regex101.com/r/Is8wZK/1 --- group 8 might have more than one word in it... sepereated by a space, but, as u can see, so does group 5, and i've exhausted my one time useage of (.+)
How can I re-write my regex to detect group 8 in exactly the way group 5 is detected?
^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+((?:[[:alpha:]]+)(?:\s+[[:alpha:]]+)*)\s+(\S+)\s+(\S+)\s+((?:[[:alpha:]]+)(?:\s+[[:alpha:]]+)*)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$
Link: https://regex101.com/r/v4mEJK/1
Pretty much all you need to do is match a group of alphabetic character and an optional group of spaces plus alphabetic characters in order to capture names which may or may not have more than one word; this is done by using
(?:[[:alpha:]]+)(?:\s+[[:alpha:]]+)*)
for groups 5 and 8.
The rest of the regex could possibly be made more specific, but there isn't really any need to add more complexity unless your input text is significantly more complex than your test case.
FWIW:
It's far better to use \s+ instead of a raw space between groups so you can match other delimiting whitespace.
I redid your generic capture groups into this:
^(\d+\/\d+\/\d+) ([A-Z]\d+) (\d+) (\d+) (.+) (\d+[A-Z]{3}\d+) (\d+) (.+) ([A-Z]) (\d+\.\d+) (\d+\.\d+) (\d+\.\d+)$
Breaking that down:
(\d+\/\d+\/\d+): this matches the date
([A-Z]\d+): this matches a capital followed by some numbers
(\d+): this matches a number
(\d+): this matches a number
(.+): this is the first general group
(\d+[A-Z]{3}\d+): this matches any number followed by 3 capitals followed by any number
(\d+): this matches a number
(.+): this is the second general group
(\d+\.\d+): this matches a number with a decimal point
(\d+\.\d+): this matches a number with a decimal point
(\d+\.\d+): this matches a number with a decimal point
This should help you get what you want.
If you are only interested in groups 5 and 8, try non capturing groups:
^(?:\d+\/\d+\/\d+) (?:[A-Z]\d+) (?:\d+) (?:\d+) (.+) (?:\d+[A-Z]{3}\d+) (?:\d+) (.+) (?:[A-Z]) (?:\d+\.\d+) (?:\d+\.\d+) (?:\d+\.\d+)$
Or only group what you need:
^\d+\/\d+\/\d+ [A-Z]\d+ \d+ \d+ (.+) \d+[A-Z]{3}\d+ \d+ (.+) [A-Z] \d+\.\d+ \d+\.\d+ \d+\.\d+$

How to make this regex allow spaces c#

I have a phone number field with the following regex:
[RegularExpression(#"^[0-9]{10,10}$")]
This checks input is exactly 10 numeric characters, how should I change this regex to allow spaces to make all the following examples validate
1234567890
12 34567890
123 456 7890
cheers!
This works:
^(?:\s*\d\s*){10,10}$
Explanation:
^ - start line
(?: - start noncapturing group
\s* - any spaces
\d - a digit
\s* - any spaces
) - end noncapturing group
{10,10} - repeat exactly 10 times
$ - end line
This way of constructing this regex is also fairly extensible in case you will have to ignore any other characters.
Use this:
^([\s]*\d){10}\s*$
I cheated :) I just modified this regex here:
Regular expression to count number of commas in a string
I tested. It works fine for me.
Use this simple regex
var matches = Regex.Matches(inputString, #"([\s\d]{10})");
EDIT
var matches = Regex.Matches(inputString, #"^((?:\s*\d){10})$");
explain:
^ the beginning of the string
(?: ){10} group, but do not capture (10 times):
\s* whitespace (0 or more times, matching the most amount possible)
\d digits (0-9)
$ before an optional \n, and the end of the string
Depending on your problem, you might consider using a Match Evaluator delegate, as described in http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.matchevaluator.aspx
That would make short work of the issue of counting digits and/or spaces
Something like this i think ^\d{2}\s?\d\s?\d{3}\s?\d{4}$
There are variants : 10 digits or 2 digits space 8 digits or 3 digits space 3 digits space 4 digits.
But if you want only this 3 variants use something like this
^(?:\d{10})|(?:\d{2}\s\d{8})|(?:\d{3}\s\d{3}\s\d{4})$

Categories

Resources