- How to Match a Phone Number with Regex and JavaScript
- Why should I even bother Learning Regex?
- Why is validating a phone number so complex?
- Let’s start with the Simplest Case
- How do I match the phone number if dashes are options?
- How about matching the phone number if there are spaces, instead of dashes?
- How to Match 1 or 1 or 1- at the beginning of our phone number
- Putting it all Together to Test an Actual Phone Number String
- Форматирование номеров телефона с помощью регулярных выражений
- Tags:
- Какое регулярное выражение подойдет для проверки номера телефона?
- Phone number regex
- The basic international phone number validation
- Extra information about validating phone number
- Create an internal tool with UI Bakery
How to Match a Phone Number with Regex and JavaScript
I’ll be honest, the first time I saw a regular expression, it was a scary experience. It looks like a weird alien language! I thought to myself: «I’ve spent months learning programming and now i gotta learn this seemly super complex language!?» However, once I sat down to actually learn regex, I discovered it’s not super hard, once you learn the syntax.
Why should I even bother Learning Regex?
As you start coding more, and more, it really comes in handy in all types of situations, and not just to valid phone numbers, and email addresses. It’s very helpful when extract data from logs, messy JSON data from API calls, and many other situations. I’m going to teach you how to valid a phone number with 1 line of code, with 1 regular expression. *Validating a phone number WITHOUT regex becomes an obnoxious leetcode question. * 😧
Why is validating a phone number so complex?
- 202-515-5555
- 202 515 5555
- (202)515 5555
- 1 202 515 5555
- 2025155555
- 1-202-515-5555
- 1202-515-5555
- etc
There are more valid combinations I didn’t list, but you get the idea! Validating every combo because a nasty coding problem. *But NOT if you’re using regex to validate it! * 😉
Let’s start with the Simplest Case
Let’s first validate 202-515-5555 . The basic idea of regex is to build a pattern to match a string. What is the pattern in 202-515-5555 ?
We start with 3 digits followed by a — followed by 3 more digits, followed by another — , then we end with 4 digits.
Here’s what the regex pattern to match 202-515-5555 looks like:
The ^ just indicates the beginning of the string. In the above regex, we’re stating that the phone number must start with \d since we have ^ in front of \d .
Now \d => stands for single digit, and simple means \d repeats exactly 3 times.
So ^\d means our phone number STARTS with 3 digits.
Now let’s just jump to the end: $ indicates the end of the string match. \d$ means our phone number must END with 4 digits. Does this make sense?
— just means the phone number must have a dash at that spot.
So let’s read the entire regex from left to right now:
- ^\d ⇾ start with 3 digits
- — ⇾ followed by a dash
- \d ⇾ followed with 3 digits
- — ⇾ followed by a dash
- \d$ ⇾ ends with 4 digits
Please read the above section a few times, if necessary, to make sure you fully understand before we move on.
How do I match the phone number if dashes are options?
Great question! How do we match BOTH: 202-515-5555 and 2025155555
To make a character match optional, just add a ? after it.
Here’s what our new improved match looks like:
-? simply means the — is optional: it may, or may not, be there!
Let’s read the entire regex again:
- ^\d ⇾ start with 3 digits
- -? ⇾ optionally followed by a dash
- \d ⇾ followed with 3 digits
- -? ⇾ optionally followed by a dash
- \d$ ⇾ ends with 4 digits
How about matching the phone number if there are spaces, instead of dashes?
Now let’s work on matching: 202-515-5555 , 2025155555 , AND 202 515 5555
Instead of optionally just having a — we can optionally have either — OR . How do we represent this? Easy, put both — and inside of [. ] like this: [ -] .
Our new regex looks like this:
Now it’s definitely starting to look alien! 😅
- ^\d ⇾ start with 3 digits
- [ -]? ⇾ optionally followed by a space OR dash
- \d ⇾ followed with 3 digits
- [ -]? ⇾ optionally followed by a space OR dash
- \d$ ⇾ ends with 4 digits
How to Match 1 or 1 or 1- at the beginning of our phone number
Based on what we’ve learned, can you figure this out?
It’s a bit tricky once you realize that the 1. in the beginning is optional.
Let’s take it step by step.
If you want the phone number to start with 1 we add ^1 to the beginning of the string match, correct? Now we want to optionally add a dash or space after the 1. Luckily, we already know how to do that: [ -]? .
Combining the 2 we get: ^1[ -]?
Adding this to our previous regex we get:
Can you sense there’s something wrong here? The above regex string match MUST start with 1 , it’s not optional. We need to make 1[ -]? optional.
How do we do that? Since we’re talking about multiple elements here: 1 and [ -]? we need to place the whole thing in (. ) creating a group. Then add a ? after it to make the entire group optional!
I know it’s a lot to take in! Here’s what it looks like:
Let’s break it down again, with an extra step now:
- ^(1[ -]?)? ⇾ optionally start with 1, which is optionally followed by a space OR dash
- \d ⇾ start with 3 digits
- [ -]? ⇾ optionally followed by a space OR dash
- \d ⇾ followed with 3 digits
- [ -]? ⇾ optionally followed by a space OR dash
- \d$ ⇾ ends with 4 digits
If you’re still reading, congrats, you now know how to think ‘regex’!
There’s still 1 outstanding issue: how to match a phone number like: (202)515 5555 . I’m going to leave that one for the reader (hint: use the pipe operator: (. |. ) ).
Putting it all Together to Test an Actual Phone Number String
Now let’s take our regex and turn it into a regular expression in javaScript. To do that you just add /. / around it. Then use a method called test :
const regex = /^(1[ -]?)?\d[ -]?\d[ -]?\d $/; const phoneNumber = '1202-515-5555'; // test returns 'true' if there's a match and 'false' if there is not const match = regex.test(phoneNumber);
If you want to learn regex properly, here’s a EXCELLENT free tutorial: RegexOne. This is literally how I learned Regex. It’s worth going through ALL the exercises.
If you enjoyed this article please check out my blog
Indepth JavaScript for more illuminating
content. 🤓
Форматирование номеров телефона с помощью регулярных выражений
Такая элементарная вещь, как номер телефона, в письменных текстах живёт во множестве вариантов. Обыкновенный номер типа +7 (123) 123-45-67 можно встретить записанным без скобок или дефисов ( +7 123 1234567 ), а то и вообще без пробелов ( +71231234567 ). Не собираюсь оскорблять чувства пишущих, им и так непросто. Но уважающий себя веб-ресурс не может допустить такой типографической разношёрстности. Плюс к тому, необлагороженные номера неудобно читать человеку (то самое human-readable).
Данная статья о том, как привести все телефонные номера на странице к однообразному виду, а также проставить корректные ссылки типа tel: на них. Для решения поставленной задачи используются регулярные выражения JavaScript. Хороший обзор регэкспов дан здесь, также почитать по теме можно на MDN.
В качестве эталонной будет принята запись номера вида +7 (123) 123-45-67 .
Найти все телефонные номера на странице можно таким способом:
let pattern = new RegExp('(\+7|8)[\s(]*\d[)\s]*\d[\s-]?\d[\s-]?\d', 'g'); // создать регулярное выражение
let phoneNumbers = document.body.innerText.match(pattern); // применить на всём тексте документа
Метод match() вернёт и запишет в переменную phoneNumbers массив (объект типа Array ) со всеми найденными на странице номерами.
Дисклеймер. Виденное выше регулярное выражение может вызвать сильное чувство боли в глазах у неподготовленного читателя. Если вы не очень знакомы с регулярками, автор всё-таки советует для начала проработать несколько первых глав учебника на LearnJavascript.
На практике встречается начало и с 8 , и с +7 .
То есть, фактически, эти части паттерна распознают первые три цифры после кода страны, причём как взятые в скобки, так и без (квантификатор * синонимичен и означает «либо ноль, либо сколько угодно»).
Данная часть паттерна распознаёт последние 7 цифр номера. Они могут быть разделены дефисами, пробелами или вообще ничем.
Напоминалка: квантификатор ? синонимичен и означает «либо одно вхождение, либо ничего»).
Ну хорошо, найти все номера получилось. К сожалению, задача этим не исчерпывается. Как же взять и заменить все вхождения разом?
Здесь поможет метод replace() . Если у регулярного выражения указан флаг ‘g’ (второй аргумент конструктора), то replace() заменит все вхождения на то, что указано. Например, задача замены всех повторяющихся пробелов в тексте на одинарные решается таким простым способом:
На всякий: /\s/g — это краткая запись для new RegExp(‘\s+’, ‘g’) . Также вместо можно писать просто + .
Но ведь у нас задача сложнее: нельзя же заменить разные номера телефонов на один! Тут самое время вспомнить о скобочных группах.
Скобочная группа — термин из теории регулярных выражений. Технически это просто часть паттерна, взятая в скобки. Но к любой такой группе можно обратиться по индексу.
К счастью, replace() поддерживает работу с группами. Достаточно написать в шаблоне замены (второй параметр) $ ( $1 или $5 ), и функция заменит эту конструкцию на содержимое скобочной группы.
То была идея, а теперь реализация:
let pattern = /(\+7|8)[\s(]?(\d)[\s)]?(\d)[\s-]?(\d)[\s-]?(\d)/g; // паттерн с проставленными скобками
let phoneNumbers = document.body.innerText.match(pattern); // найдём все номера
let correctNumber = phoneNumbers[0].replace(pattern, '+7 ($2) $3-$4-$5'); // пробуем замену
console.log(correctNumber);
В результате будет выведен аккуратный, каноничный телефонный номер. Работает!
Теперь, чтобы заменить все найденные номера телефонов на единообразные, добавим флаг g :
let pattern = /(\+7|8)[\s(]?(\d)[\s)]?(\d)[\s-]?(\d)[\s-]?(\d)/g;
document.body.innerHTML = document.body.innerHTML.replace(pattern, '+7 ($2) $3-$4-$5');
Усложним шаблон функции replace() , чтобы номер телефона был кликабельным (ссылка с префиксом tel: ):
То есть, для корректной работы ссылки нужно в её коде выписать все цифры номера подряд — как раз самый неудобный для чтения человеком вариант.
Tags:
Какое регулярное выражение подойдет для проверки номера телефона?
Здравствуйте!
Подскажите пожалуйста регулярное выражение для использования js для проверки правильности номера телефона который может быть написан в нескольких из этих форматов
8(ddd)ddddddd;
+7(ddd)ddddddd;
8dddddddddd;
+7dddddddddd;
Заранее спасибо.
Проверка будет производится на стране браузера клиента
Тоже столкнулся с проблемой валидизации телефонных номеров.
Телефоны берутся с участников вебинаров, на которые записываются люди из очень разных стран.
Соответственно, со всеми предыдущими схемами возникают проблемы:
1) а что если телефон с Украины (не +7-, а +38-)? А из Казахстана? А США (1-)? А Уганда ( +233-)? (из Уганды, правда, пока слушателей не было, но все впереди).
2)В разных местностях приняты самые невообразимые способы разбиения телефона на группы цифр:
8(8888)8-88-88-88 например. или 888(88)88888-888. Да и какие угодно могут возникнуть в будущем.
Поэтому вариант с «дефолтным разбиением типа «8(888)888-88-88 ну совершенно не катит.
Соответственно, я придумал следующий валидатор:
1) В начале могут быть пробелы, после них может быть «+» (а может и не быть)
2) Дальше должна идти группа цифр в количестве от 10 до 14 (мне нужны номера в международном формате; но если кому-то нужны более короткие — можно исправить диапазон длин).
3) Поскольку я не знаю, как люди группируют цифры — до и после каждой цифры может быть один из 8 знаков («-«, » «, «_», «(«, «)», «:», «=», «+»). Это значит, что между двумя цифрами могут быть любые два из этих знаков.
В итоге получилось очень коротко и понятно )) :
/^(\s*)?(\+)?([- _():=+]?\d[- _():=+]?)(\s*)?$/
Съедает следующие телефоны:
+7(903)888-88-88
8(999)99-999-99
+380(67)777-7-777
001-541-754-3010
+1-541-754-3010
19-49-89-636-48018
+233 205599853
Phone number regex
The regular expressions below can be used to validate if a string is a valid phone number format and to extract a phone number from a string. Please note that this validation can not tell if a phone number actually exists.
The basic international phone number validation
A simple regex to validate string against a valid international phone number format without delimiters and with an optional plus sign:
Enter a text in the input above to see the result
Example code in Javascript
The more complex phone number validation
This regular expression will match phone numbers entered with delimiters (spaces, dots, brackets, etc.)
Enter a text in the input above to see the result
Example code in Javascript
Enter a text in the input above to see the result
Extra information about validating phone number
While validation of phone numbers using regex can give a possibility to check the format of the phone number, it does not guarantee that the number exists.
There might be also an option to leave a phone number field without any validation since some users might have:
- More complex phone numbers with extensions
- The different phone numbers for calling them on a different time of day
Create an internal tool with UI Bakery
Discover UI Bakery – an intuitive visual internal tools builder.