I need a regex that validates for minimum 7 digits in the given string

29,881

Solution 1

Seven or more digits, mixed with any number of any other kind of character? That doesn't seem like a very useful requirement, but here you go:

^\D*(?:\d\D*){7,}$

Solution 2

(?:\d.*){7,}
  • (?:...) - group the contained pattern into an atomic unit
  • \d - match a digit
  • .* match 0 or more of any character
  • {7,} match 7 or more of the preceeding pattern

If the only separators you want to ignore are spaces, dashes, parentheses, and the character 'X', then use this instead:

(?:\d[- ()X]*){7,}
  • [...] creates a character class, matching any one of the contained characters

The difference being, for example, that the first regex will match "a1b2c3d4e5f6g7h", and the second one won't.

As Gregor points out in the comments, the choice of regex depends on what function you're using it with. Some functions expect a regex to match the entire string, in which case you should add an extra .* in front to match any padding before the 7 digits. Some only expect a regex to match part of a string (which is what I expected in my examples).

According to the documentation for IsMatch() it only "indicates whether the regular expression finds a match in the input string," not requires it to match the entire string, so you shouldn't need to modify my examples for them to work.

Solution 3

Why do you want to use regular expressions for this? The first Validate function you posted which simply counts the number of digits is vastly more comprehensible, and probably faster as well. I'd just ditch the unnecessary ToCharArray call, collapse the predicate into the Count function and be done with it:

s.Count(char.IsDigit) >= 7;

Note that if you only want to accept 'normal' numbers (i.e. 0-9) then you'd want to change the validation function, as IsDigit matches many different number representations, e.g.

s.Count(c => c >= '0' && c <= '9') >= 7;
Share:
29,881
Shimmy Weitzhandler
Author by

Shimmy Weitzhandler

Updated on July 24, 2020

Comments

  • Shimmy Weitzhandler
    Shimmy Weitzhandler almost 4 years

    I wanna validate a phone number. My condition is that I want mimimum 7 numbers in the given string, ignoring separators, X, parantheses.

    Actually I want to achieve this function in regex:

    Func<string, bool> Validate = s => s.ToCharArray().Where(char.IsDigit).Count() >= 7;
    Func<string, bool> RegexValidate = s => System.Text.RegularExpressions.Regex.IsMatch(s, @"regex pattern should come here.")
    string x = "asda 1234567 sdfasdf";
    string y = "asda   sdfa 123456 sdfasdf";
    
    bool xx = Validate(x); //true
    bool yy = Validate(y); //false
    

    The purpose of my need is I want to include this regex in an asp:RegularExpressionValidator

  • Grzegorz Oledzki
    Grzegorz Oledzki almost 15 years
    If the regexp is to be used with 'match' not 'find', then you need another ".*" in front.
  • Shimmy Weitzhandler
    Shimmy Weitzhandler almost 15 years
    please refer to my function. I need 1 thing: validate that there are 7+ numbers in the string, nothing else.
  • rampion
    rampion almost 15 years
    Good point. Not sure which language Shimmmy was talking about, so good to know.
  • Philippe Leybaert
    Philippe Leybaert almost 15 years
    This is the only regex that does what the OP wants. Good job
  • Shimmy Weitzhandler
    Shimmy Weitzhandler almost 15 years
    Thanks, finally, that's what I want to validate. period.
  • rampion
    rampion almost 15 years
    @activa - I fail to see where mine fails. If you could explain it to me, I'd appreciate the education!
  • Tom
    Tom almost 15 years
    Can you explain what \D means? I never came across that.
  • Tom
    Tom almost 15 years
    @Shimmy: instead of just saying "it doesn't work"... how about you show rampion an input that it fails on... I think it's obvious he wants to understand why it is wrong (and at a glance, his regex seems right). (Again, this seems silly that you are using regex for this anyways).
  • rampion
    rampion almost 15 years
    @Shimmy - the /.../ are a conventional way to denote the beginning and ending of a regex. Some languages (like C#) don't use them in the regex themselves, some (like perl, ruby, and awk) do. They might have been why the examples weren't working for you.
  • rampion
    rampion almost 15 years
    \D is the opposite of \d. \D means anything that's not a digit.
  • Tom
    Tom almost 15 years
    @Shimmy: all the time you are telling us you NEED a regex could have been spent telling us why... I think Greg is perfectly valid for suggesting this alternative since it's a much better approach to solving the main problem you are trying to solve...
  • OregonGhost
    OregonGhost almost 15 years
    Again, be aware that a digit in .NET's regexes includes arabic numbers, so this may not be exactly what you want. More details in Raymond Chen's blog at blogs.msdn.com/oldnewthing/archive/2004/03/09/86555.aspx
  • Tom
    Tom almost 15 years
    I wish others would confirm that this regex works... because I think rampion deserves some credit since he had it right from the beginning.
  • OregonGhost
    OregonGhost almost 15 years
    As I pointed out in Alan's answer, this regex will also match arabic numbers, though that might not be wanted in this case.
  • Meydjer Luzzoli
    Meydjer Luzzoli almost 15 years
    Indeed. A lot of people say they need things, but it's often because they don't really know what they need, and it's the way they believe they should do it. If you actually said why a regex is the way you have to do it, even though it is clearly not the most appropriate way to do it, then you'd get further than just ranting.
  • Meydjer Luzzoli
    Meydjer Luzzoli almost 15 years
    One of the responsibilities of people who answer on these forums is to try to guide people to better choices than they were perhaps going to make before they asked the question. It's one of the reasons that this site can be better than Google, because you can also find answers you weren't looking for. As such, if you are looking for a sub-optimal solution because you have constraints imposed, then it's typically worthwhile indicating that you know what you're trying to do is sub-optimal, and some indication of the constraints that make it so.
  • Shimmy Weitzhandler
    Shimmy Weitzhandler almost 15 years
    These are considered number for what I need: 0123456789 But you got a point dude.
  • OregonGhost
    OregonGhost almost 15 years
    The point is that 0-9 are not the only characters considered as a number by \d (or, more exactly, Char.IsDigit()), yet 0-9 is typically anything that is allowed in phone numbers, and int.Parse will also throw with arabic digits.
  • Shimmy Weitzhandler
    Shimmy Weitzhandler almost 15 years
    I am sorry, I added comments to the question that explains the purpose of my 'NEED'
  • Alan Moore
    Alan Moore almost 15 years
    @rampion, the character class [ -()X] in that second regex is equivalent to [ !"#$%&'()X] - you forgot to escape the hyphen.
  • nasch
    nasch over 6 years
    @OregonGhost I'm really curious what you mean by "also" Arabic numbers? 0-9 are the Arabic numerals, so what else did you have in mind?
  • OregonGhost
    OregonGhost over 6 years
    @nasch: Eastern Arabic numerals in Arabic script. What you call Arabic numerals are Arabic numerals in Latin script. I guess this is true for all numerals listed in en.wikipedia.org/wiki/Hindu%E2%80%93Arabic_numeral_system. The point is that \d matches both 2 and ٣ - but int.Parse throws an exception by default (i.e. invariant culture) on the latter. Just verified that with LinqPad.