1

I current have the following regular expression to accept any numeric value that is seven digits

^\d{7}

How do I improve it so it will accept numeric values that are seven or ten digits?

Pass: 0123456, 1234567, 0123456789, 123467890
Fail: 123456, 12345678, 123456789

1
  • What language are you using? Not all regex are equal. Commented May 25, 2010 at 21:23

3 Answers 3

5

A simple solution is this:

^\d{7}(\d{3})?$

There are at least two things to note with this solution:

  • In a unicode context \d may match far more than you intended (for example foreign characters that are digits in other non-Latin languages).
  • This regular expression contains a capturing group. You probably don't want that. You can fix this by changing it to a non-capturing group (?: ... ).

So for these reasons you may want to use this slightly longer expression instead:

^[0-9]{7}(?:[0-9]{3})?$

Here's a little testbed in C# so that you can see it works:

for (int i = 0; i < 12; ++i)
{
    string input = new string('0', i);
    bool isMatch = Regex.IsMatch(input, "^[0-9]{7}(?:[0-9]{3})?$");
    Console.WriteLine(i.ToString().PadLeft(2) + ": " + isMatch);
}

Result:

 0: False
 1: False
 2: False
 3: False
 4: False
 5: False
 6: False
 7: True
 8: False
 9: False
10: True
11: False
Sign up to request clarification or add additional context in comments.

3 Comments

The regex pattern ^[0-9]{7}(?:[0-9]{3})?$ worked for every scenario
@Michael Kniskern: Great! This question was actually more difficult than it first appeared to be. All three posters initially posted an answer which appeared to be correct but was actually wrong! Even the voters did not notice the errors, upvoting the wrong solutions.
@Mark. Thanks for your effort. I feel like every time I enter the world of regular expressions, I am playing a dangerous game.
3

Edit: This is wrong, but I'm going to undelete it and leave it around for reference purposes, since the upvotes suggest people thought it was right. The correct solution is here


I think just:

^\d{7}\d{3}?

6 Comments

@Mark You mean because it doesn't have a trailing $? I left it out because the OP did, but yes, technically :)
Yes, but it matches the original regex's "looseness". :)
@Mark It does if you're doing whole-string matching
I want '12345678' to fail. It can only accept numeric values that are 7 or ten digits in length.
In \d{3}? the ? turns the {3} into a reluctant quantifier--in other words, it has no effect. ^\d{7}\d{3}? matches any string that starts with ten digits.
|
2

Why not a literal interpretation of what you're looking for:

^\d{7}|\d{10}$

1 Comment

Except that won't work quite right either, because that's literally ^\d{7} or \d{10}$. You need to add a a non-capturing group in there, like ^(?:\d{7}|\d{10})$.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.