Phone number regex: five common patterns tested against every numbering plan
A phone number is valid when its country's numbering plan allocates it, and 245 plans allocate differently: lengths from four digits to thirteen, trunk prefixes or none, mobile ranges anywhere in the number space. A single regular expression can check a shape; it cannot know the plans. Here is how far five common shapes get, tested against the 1,132example numbers the 245 plans publish, written three ways, and against 4,241 numbers made from them one digit short or long, which no plan allocates.
The results
Share of the plans' example numbers each pattern accepts, as E.164 (+447400123456), in international form (+44 7400 123456) in national form (07400 123456) and in national form with the punctuation stripped (07400123456), as many forms do before validating; and share of the wrong numbers it lets through, as E.164 and as national digits. A good validator accepts all of the first four and none of the last two.
| Pattern | E.164 | International | National | National, digits only | Wrong, E.164 | Wrong, national digits |
|---|---|---|---|---|---|---|
Ten digits^\d{10}$exactly ten digits, nothing else | 0% | 0% | 0% | 38.9% | 0% | 13.9% |
North American^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$three, three and four digits, with optional brackets, dashes, dots or spaces | 0% | 0% | 20.1% | 38.9% | 0% | 13.9% |
E.164 shape^\+[1-9]\d{1,14}$a plus, then two to fifteen digits, the first not 0 | 100% | 0% | 0% | 0% | 100% | 0% |
Seven to fifteen digits^\+?\d{7,15}$an optional plus, then seven to fifteen digits | 99.9% | 0% | 0.7% | 95.1% | 99.6% | 91.2% |
Loose international^\+?(\d{1,3})?[-.\s]?\(?\d{1,4}\)?[-.\s]?\d{1,4}[-.\s]?\d{1,9}$an optional plus and country code, then groups of digits with optional separators | 100% | 82.4% | 91.4% | 100% | 100% | 100% |
| The plans' own patternsthe number read by its country's plan (the guides' parse, every plan loaded) | 100% | 100% | 99.6% | 99.6% | 0% | 0% |
No shape does both jobs. The loose international pattern accepts 82.4% of the numbers written internationally and 100% of the wrong ones; seven to fifteen digits accepts 99.9% of the E.164 numbers and 99.6% of the wrong ones — a number one digit short of a United Kingdom mobile is still seven to fifteen digits. Ten digits, punctuation stripped, accepts 38.9% of the national numbers, every plan whose national form happens to be ten digits long, and 13.9% of the wrong ones: an eleven-digit number one digit short, or a nine-digit one one digit long, has ten digits. The plans' own patterns accept every example and no wrong number, with one gap in the national forms: Argentina's 011 15-2345-6789 and Belarus's 8 029 491-19-11, written with a prefix the file does not strip; their international forms (+54 9 11 2345-6789, +375 29 491-19-11) read.
Number by number
| Number | Ten digits | North American | E.164 shape | Seven to fifteen digits | Loose international | The plan |
|---|---|---|---|---|---|---|
| 07400 123456United Kingdom, national | — | — | — | — | accepts | valid |
| +447400123456United Kingdom, E.164 | — | — | accepts | accepts | accepts | valid |
| 01512 3456789Germany, national | — | — | — | — | accepts | valid |
| +4915123456789Germany, E.164 | — | — | accepts | accepts | accepts | valid |
| (201) 555-0123United States, national | — | accepts | — | — | accepts | valid |
| +12015550123United States, E.164 | — | — | accepts | accepts | accepts | valid |
| 06 12 34 56 78France, national | — | — | — | — | — | valid |
| +33612345678France, E.164 | — | — | accepts | accepts | accepts | valid |
| 081234 56789India, national | — | — | — | — | accepts | valid |
| +918123456789India, E.164 | — | — | accepts | accepts | accepts | valid |
| +44740012345United Kingdom, one digit short | — | — | accepts | accepts | accepts | not a number |
What validates instead
- The plan's pattern, per country. Every plan defines its ranges as patterns over the national significant number. The United Kingdom's mobile ranges, for one:
^(?:7(?:457[0-57-9]|700[01]|911[028])\d{5}|7(?:[1-3]\d\d|4(?:[0-46-9]\d|5[0-689])|5(?:0[0-8]|[13-9]\d|2[0-35-9])|7(?:0[1-9]|[1-7]\d|8[02-9]|9[0-689])|8(?:[014-9]\d|[23][0-8])|9(?:[024-9]\d|1[02-9]|3[0-689]))\d{6})$. The regex builder combines the line types you accept for any country and writes the validator in nine languages. - Read the number first, then match. People type spaces, brackets, a trunk prefix, an exit code. Strip the punctuation, find the country code (or take the user's country), drop the trunk prefix the plan defines, then match the national number against that plan. That is what the guides' file does: JavaScript, Python and six more languages, tested.
- Keep the shape check where it belongs.
^\+[1-9]\d{1,14}$is right for a value that must already be E.164, in a database constraint or at an API boundary (E.164). It says nothing about whether the number exists. - Know what no pattern answers. Whether a valid number is in service, and who serves it today, is a question for the networks (line types at signup).
How this was measured: every line type of every plan that publishes an example number, written as E.164, in the plan's international form and in its national form; the wrong numbers are those examples with the last digit dropped or repeated, kept when no plan accepts them. Plans as of 2026-10-25; the patterns as written above, in JavaScript.