🔍 Phone Number Regex Builder (30+ Countries)
Instantly generate validation regex for phone numbers across 30+ countries. Four variants (E.164 / International / Flexible / Mobile-only), multi-country OR combination, live tester and ready-to-paste snippets for JavaScript, PHP, Python, Ruby and Go. Perfect for form validation, log extraction and data cleansing.
🔒 About Privacy
- ・All processing runs entirely in your browser (JavaScript)
- ・The phone numbers you enter are never sent to any server
📝 Generated regex
/^.+$/g
🧪 Live tester
💻 Code snippets per language
📖 Where people get stuck
Generates phone number validation patterns for more than thirty countries, in four variants (E.164, international, lenient and mobile-only), with OR-combination across countries, a live tester and snippets for JavaScript, PHP, Python, Ruby and Go. Everything runs in the browser. What a regular expression can decide, however, is only whether the shape looks like a number — it cannot tell you whether that number exists, is still in service, or can receive an SMS. And numbering plans change: allocate a new leading digit and a pattern that was correct yesterday starts rejecting real numbers today.
| Case | What happens | What to do |
|---|---|---|
| An over-strict pattern rejects real numbers | Numbering schemes are managed by each country regulator and change every few years — new leading digits are added for mobile, area codes are split, ranges are created for new services. A pattern that enumerates leading digits in detail is accurate at the moment it is written and gradually begins to reject real numbers. And because of number portability, the inference that a given prefix means mobile and therefore SMS-capable no longer holds — the mapping from range to carrier is not fixed. Meanwhile the rejected user leaves without knowing why — someone holding a perfectly valid number who is told it is invalid has no move available to them. | Use the pattern only to reject input that is obviously wrong. Concretely, keep it to a minimum and maximum length, the permitted character set, and a plausible country code — enumerating the first three digits is safer left unwritten unless you are prepared to keep maintaining it. Where correctness matters — SMS verification, identity checks, billing — use a maintained library: libphonenumber tracks national numbering plans continuously, and there is no reason to take that work on yourself. The only way to establish that a number is actually reachable is to send to it — and once you send a verification code by SMS, the precision of your regular expression stops mattering to the final result. |
| Validating before normalizing | People write the same number in many different ways — with and without hyphens, separated by spaces, in parentheses, with and without the country code, with and without a leading zero, and in full-width digits. Copy from a smartphone contact list and invisible control characters and unusual spaces can come along too. Feed the raw string to a pattern and all of these come out invalid — and the person who typed it cannot see what is different (full-width and half-width digits differ only in width in many fonts). The other awkward case is the leading zero in national versus international format — in many countries a number carries a leading 0 domestically and drops it when the country code is prefixed. If you want to accept both, you have no choice but to convert to one form before comparing. |
Fix the order as normalize, validate, store. To normalize: convert full-width to half-width (see the width converter) and strip everything except digits and a leading + — that alone absorbs most of the variation listed above. Validate against the normalized string, and store in E.164 form, meaning + followed by the country code and digits only — in that form, comparison, duplicate detection and international sending all work directly. Format it to local convention only when displaying it. And allow hyphens and spaces in the input field — telling the user to enter digits only is just pushing the normalization work onto them. |
| The pattern behaves differently in each engine | The tester here runs on the JavaScript engine, so a pattern that passes there does not necessarily behave the same where you paste it. Three differences stand out. The Go regexp package is RE2, so lookahead ((?=...)) and backreferences are unavailable — a pattern containing them fails at compile time. PHP preg_match requires delimiters; without wrapping in /.../ it warns and matches nothing. Anchors vary too — $ in many engines also matches just before a trailing newline, so an input like a number followed by a newline and further text can slip through (in JavaScript and Python you need \z or \Z, or to strip newlines first). |
Always run the generated pattern once in the language you will actually use. Go in particular does not misbehave, it fails at startup, so without a test you find out in production. Prepare three kinds of test case: valid numbers that must pass, obviously wrong input that must be rejected, and boundaries — shortest, longest, with and without country code. Including the input that must be rejected is the crucial part — test only the happy path and a broken pattern that accepts everything still shows green. And do not inline the pattern in your code: give it a name and keep it in one place — so that when the numbering plan changes, there is a single place to fix. |
How strict to be follows from what the number is for. On an optional field in a contact form, strict validation only reduces the number of enquiries — if you cannot be reached, the person who loses out is the one who typed it, and you do not need to adjudicate on their behalf. Conversely, for SMS verification or a delivery contact, failing to send is an immediate operational failure, so put actual reachability, meaning sending a verification code, into the process rather than relying on format validation. Treating those two cases with the same strictness is the most common design mistake. Also, a phone number is personal data — do not print it to logs, do not include it in error messages, and do not pass it to analytics as a URL parameter. Designs that send the in-progress value to a validation API in real time deserve particular care. And avoid displaying only the word invalid — state how many digits are expected and whether the country code is needed, and show an example; most input mistakes resolve themselves on the spot.
📖 How to Use
-
1
Pick target countriesPick a single country or several to combine into one OR pattern (perfect for international forms). 30+ countries supported.
-
2
Choose a variantPick from E.164 (strict + country-code), International (with separators), Flexible (intl + national) or Mobile-only.
-
3
Copy or testCopy the regex with one click. Paste a list of numbers into the live tester to see matches and failures in real time.
-
4
Paste into your languageReady-to-run snippets for JavaScript, PHP, Python, Ruby, Go and Java are generated automatically with proper escaping.
❓ Frequently Asked Questions
Why not use libphonenumber?
What is the difference between International and E.164?
Can I combine multiple countries into one regex?
Is the generated regex perfect?
🔗 Related Tools
- ・Phone Number Formatter — Convert to International / National / E.164 / tel: URI
- ・Regex Tester — Real-time JavaScript regex testing
- ・Email Validator — RFC 5322, disposable & role-account detection
🐛 Found a bug or issue with this tool?
Free to use, no signup. Even just the steps to reproduce are helpful. Reports go directly to the operator and help us fix issues.
Thanks for your report!
Your report has been delivered to the operator and will be used to improve the tool.