tags:

views:

61

answers:

3

I'm trying to create a regex expression to match any string that has exactly 9 digits. the digits can exist anywhere in the string.

For example, if you passed in the following strings, you'd get a match: 123456789 123aeiou456abc789

These strings would fail to provide a match 12345678 1234567890

+6  A: 

Try this:

@"^(\D*\d){9}\D*$"

Or use this improved version. It assumes that you only want to match 0-9 and not other characters that represent digits in other languages. It also uses a non-capturing group to improve performance:

"^(?:[^0-9]*[0-9]){9}[^0-9]*$"

Here's a breakdown of what it means:

^        Start of string.
(?:      Start a non-capturing group.
[^0-9]*  Match zero or more non-digits.
[0-9]    Match exactly one digit.
)        Close the group.
{9}      Repeat the group exactly 9 times.
[^0-9]*  Match zero or more non-digits.
$        End of string.

Here's a testbed for it:

string regex = "^(?:[^0-9]*[0-9]){9}[^0-9]*$"
string[] tests = {
                     "123456789",
                     "123aeiou456abc789",
                     "12345678",
                     "1234567890"
                 };
foreach (string test in tests)
{
    bool isMatch = Regex.IsMatch(test, regex); 
    Console.WriteLine("{0}: {1}", test, isMatch);
}

Results:

123456789: True
123aeiou456abc789: True
12345678: False
1234567890: False
Mark Byers
+1 - pretty much what I would have posted. Note, however, that `\d` *may* match other digits than 0..9 in Unicode environments (such as 0xFF10..0xFF19).
Lucero
The capturing groups have to be improved, but yes, it works this way. The result will be like 18 groups, of which 9 contain a single digit ... +1
tanascius
RE:Lucero's, if the Unicode bit is a problem, the `\d` could always be replaced with `[0-9]`.
eidylon
@eidylon, I know, it was a hint because many people believe that `\d` will just match the ASCII 0..9, which is not true. The question states 9 digits, which is what the expression of Mark handles, but it would also match ٠١٢٣٤٥٦٧٨٩ for instance.
Lucero
@tanascius, no, "only" 1 group with 9 captures. And it is easy to get rid of them by using `(?:` to open the group.
Lucero
@Lucero: yes, that is the better way to go ..
tanascius
Thank you all - Great job Mark!
Nick
I've included some suggestions from the comments in the answer, thanks all.
Mark Byers
A: 

Here's my take: ^[^0-9]*[0-9]{9}[^0-9]*$

FWIW, there is a REALLY cool little app to help you build RegEx's which will parse them and explain what your expression is doing in plain English as well as providing an actual UI to help you add expressions you may not be very familiar with. Check out Expresso.

eidylon
this does not match `123aeiou456abc789`, where the digits are spread over the input
tanascius
Ah yes, this one does look for them all contiguous. RegEx withdrawn.
eidylon
Thanks eidylon - expresso is now in my toolkit
Nick
+1  A: 

check out the website

http://www.regexlib.com/CheatSheet.aspx

I found it tobe very helpful.

VoodooChild