Несколько PHP-функций для форматирования телефонных номеров.
1
Формат +7 (xxx) xxx-xx-xx
Формат +7 (xxx) xxx-xx-xx очень распространён, но правильнее писать номера без скобок. В нормах русского языка скобки используются для поясняющей и дополняющей информации, а так как без кода оператора или города дозвониться до абонента не получится, то это уже не дополнительная информация.
function phone_format($phone)
{
$phone = trim($phone);
$res = preg_replace(
array(
'/[+]?([7|8])[-|s]?([-|s]?(d{3})[-|s]?)[-|s]?(d{3})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?(d{3})[-|s]?(d{3})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?([-|s]?(d{4})[-|s]?)[-|s]?(d{2})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?(d{4})[-|s]?(d{2})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?([-|s]?(d{4})[-|s]?)[-|s]?(d{3})[-|s]?(d{3})/',
'/[+]?([7|8])[-|s]?(d{4})[-|s]?(d{3})[-|s]?(d{3})/',
),
array(
'+7 ($2) $3-$4-$5',
'+7 ($2) $3-$4-$5',
'+7 ($2) $3-$4-$5',
'+7 ($2) $3-$4-$5',
'+7 ($2) $3-$4',
'+7 ($2) $3-$4',
),
$phone
);
return $res;
}
PHP
Тестирование и результаты
Мобильные и городские:
echo phone_format('+7 (495) 1234567');
echo phone_format('+8 (495) 123 45 67');
echo phone_format('+7(495)123-45-67');
echo phone_format('+7(495)1234567');
echo phone_format('+7 495 123-45-67');
echo phone_format('+8 495 123 45 67');
echo phone_format('+7 495 1234567');
echo phone_format('+7-495-123-45-67');
echo phone_format('84951234567');
PHP
+7 (495) 123-45-67
+7 (495) 123-45-67
+7 (495) 123-45-67
+7 (495) 123-45-67
+7 (495) 123-45-67
+7 (495) 123-45-67
+7 (495) 123-45-67
+7 (495) 123-45-67
+7 (495) 123-45-67
Региональные:
echo phone_format('7 4734 12-34-56');
echo phone_format('7 4735 123-456');
PHP
+7 (4734) 12-34-56
+7 (4735) 123-456
С текстом:
echo phone_format('+7-495-123-45-67 Иван');
echo phone_format('+84951234567 доп. 123');
echo phone_format('+74951234567, +79031234567');
echo phone_format('тел. +84951234567');
PHP
+7 (495) 123-45-67 Иван
+7 (495) 123-45-67 доп. 123
+7 (495) 123-45-67, +7 (903) 123-45-67
тел. +7 (495) 123-45-67
Номера с ошибками:
echo phone_format('495 1234567');
echo phone_format('8(8001234567');
echo phone_format('8800;1234567');
PHP
495 1234567
8(8001234567
8800;1234567
2
Формат +7 xxx xxx-xx-xx
function phone_format($phone)
{
$phone = trim($phone);
$res = preg_replace(
array(
'/[+]?([7|8])[-|s]?([-|s]?(d{3})[-|s]?)[-|s]?(d{3})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?(d{3})[-|s]?(d{3})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?([-|s]?(d{4})[-|s]?)[-|s]?(d{2})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?(d{4})[-|s]?(d{2})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?([-|s]?(d{4})[-|s]?)[-|s]?(d{3})[-|s]?(d{3})/',
'/[+]?([7|8])[-|s]?(d{4})[-|s]?(d{3})[-|s]?(d{3})/',
),
array(
'+7 $2 $3-$4-$5',
'+7 $2 $3-$4-$5',
'+7 $2 $3-$4-$5',
'+7 $2 $3-$4-$5',
'+7 $2 $3-$4',
'+7 $2 $3-$4',
),
$phone
);
return $res;
}
PHP
Результат:
/* Мобильные и городские */
+7 495 123-45-67
+7 495 123-45-67
+7 495 123-45-67
+7 495 123-45-67
+7 495 123-45-67
+7 495 123-45-67
+7 495 123-45-67
+7 495 123-45-67
+7 495 123-45-67
/* Региональные */
+7 4734 12-34-56
+7 4735 123-456
/* С текстом */
+7 495 123-45-67 Иван
+7 495 123-45-67 доп. 123
+7 495 123-45-67, +7 903 123-45-67
тел. +7 495 123-45-67
/* Номера с ошибками */
495 1234567
8(8001234567
8800;1234567
3
Формат +7-xxx-xxx-xx-xx
function phone_format($phone)
{
$phone = trim($phone);
$res = preg_replace(
array(
'/[+]?([7|8])[-|s]?([-|s]?(d{3})[-|s]?)[-|s]?(d{3})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?(d{3})[-|s]?(d{3})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?([-|s]?(d{4})[-|s]?)[-|s]?(d{2})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?(d{4})[-|s]?(d{2})[-|s]?(d{2})[-|s]?(d{2})/',
'/[+]?([7|8])[-|s]?([-|s]?(d{4})[-|s]?)[-|s]?(d{3})[-|s]?(d{3})/',
'/[+]?([7|8])[-|s]?(d{4})[-|s]?(d{3})[-|s]?(d{3})/',
),
array(
'+7-$2-$3-$4-$5',
'+7-$2-$3-$4-$5',
'+7-$2-$3-$4-$5',
'+7-$2-$3-$4-$5',
'+7-$2-$3-$4',
'+7-$2-$3-$4',
),
$phone
);
return $res;
}
PHP
Результат:
/* Мобильные и городские */
+7-495-123-45-67
+7-495-123-45-67
+7-495-123-45-67
+7-495-123-45-67
+7-495-123-45-67
+7-495-123-45-67
+7-495-123-45-67
+7-495-123-45-67
+7-495-123-45-67
/* Региональные */
+7-4734-12-34-56
+7-4735-123-456
/* С текстом */
+7-495-123-45-67 Иван
+7-495-123-45-67 доп. 123
+7-495-123-45-67, +7 903 123-45-67
тел. +7-495-123-45-67
/* Номера с ошибками */
495 1234567
8(8001234567
8800;1234567
TEXT
In this short tutorial, we’re going to look at validating a phone number in PHP. Phone numbers come in many formats depending on the locale of the user. To cater for international users, we’ll have to validate against many different formats.
In this article
- Validating for Digits Only
- Checking for Special Characters
- International Format
- Key Takeaways
- 10 minute read
Validating for Digits Only
Let’s start with a basic PHP function to validate whether our input telephone number is digits only. We can then use our isDigits function to further refine our phone number validation.
We use the PHP preg_match function to validate the given telephone number using the regular expression:
/^[0-9]{'.$minDigits.','.$maxDigits.'}z/
This regular expression checks that the string $s parameter only contains digits [0-9] and has a minimum length $minDigits and a maximum length $maxDigits. You can find detailed information about the preg_match function in the PHP manual.
Checking for Special Characters
Next, we can check for special characters to cater for telephone numbers containing periods, spaces, hyphens and brackets .-(). This will cater for telephone numbers like:
- (012) 345 6789
- 987-654-3210
- 012.345.6789
- 987 654 3210
The function isValidTelephoneNumber removes the special characters .-() then checks if we are left with digits only that has a minimum and maximum count of digits.
International Format
Our final validation is to cater for phone numbers in international format. We’ll update our isValidTelephoneNumber function to look for the + symbol. Our updated function will cater for numbers like:
- +012 345 6789
- +987-654-3210
- +012.345.6789
- +987 654 3210
The regular expression:
/^[+][0-9]/
tests whether the given telephone number starts with + and is followed by any digit [0-9]. If it passes that condition, we remove the + symbol and continue with the function as before.
Our final step is to normalize our telephone numbers so we can save all of them in the same format.
Key Takeaways
- Our code validates telephone numbers is various formats: numbers with spaces, hyphens and dots. We also considered numbers in international format.
- The validation code is lenient i.e: numbers with extra punctuation like 012.345-6789 will pass validation.
- Our normalize function removes extra punctuation but wont add a + symbol to our number if it doesn’t have it.
- You could update the validation function to be strict and update the normalize function to add the + symbol if desired.
Задача. Есть большой список телефонных номеров, которые нужно переформатировать под единый формат (или форматы). Номера есть нескольких типов 7, 10 и 11 значные. Для каждого из этих типов необходимо вывести номер телефона в своем формате.
В php есть такие функции как money_format и number_format, но нет такой функции как phone_format, этот пробел я и решил восполнить написав такую функцию для форматирования телефонных номеров.
/**
* Форматирование телефонного номера
* по шаблону и маске для замены
*
* @param string $phone
* @param string|array $format
* @param string $mask
* @return bool|string
*/
function phone_format($phone, $format, $mask = '#')
{
$phone = preg_replace('/[^0-9]/', '', $phone);
if (is_array($format)) {
if (array_key_exists(strlen($phone), $format)) {
$format = $format[strlen($phone)];
} else {
return false;
}
}
$pattern = '/' . str_repeat('([0-9])?', substr_count($format, $mask)) . '(.*)/';
$format = preg_replace_callback(
str_replace('#', $mask, '/([#])/'),
function () use (&$counter) {
return '${' . (++$counter) . '}';
},
$format
);
return ($phone) ? trim(preg_replace($pattern, $format, $phone, 1)) : false;
}
Использование
Передаем в качестве параметров не отформатированный номер телефона, шаблон и маску для замены. В качестве шаблона также можно передать массив ключи которого это количество цифр в телефоне, а значение шаблоны замены
$phones = array(
'926 111-2233',
'9261112233',
'8 (926) 111 22 33',
'8 926 111-22-33',
'559-8833',
'5598833',
'',
'qweqwe'
);
$formats = array(
'7' => '###-##-##',
'10' => '+7 (###) ### ####',
'11' => '# (###) ### ####'
);
foreach ($phones AS $phone) {
echo phone_format($phone, $formats, '#');
}
Результат выполнения радует глаз:
+7 (926) 111 2233
+7 (926) 111 2233
8 (926) 111 2233
8 (926) 111 2233
559-88-33
559-88-33
Данный сниппет не ставит перед собой цель определить город, регион или какой-либо другой параметр. Кроме того возникнут проблемы при использовании шаблонов для номеров “8 (123) 111-22-33” и “+7 (123) 111-22-33”. Возможно потом придумаю как поступать с такими номерами.
- Use the
preg_match()Function to Format Phone Numbers in PHP - Use the
sprintf()Function to Format Phone Numbers in PHP

In this article, we will talk about different methods to format phone numbers using PHP. We will format the phone number from +13335092344 to 333-509-2344.
Use the preg_match() Function to Format Phone Numbers in PHP
We can use the built-in function preg_match() to format phone numbers. This function searches a specified pattern from a string. The correct syntax to use this function is as follows.
preg_match($pattern, $inputString, $matches, $flag, $offset);
The built-in function preg_match() has five parameters. The details of its parameters are as follows
| Parameters | Description | |
|---|---|---|
$pattern |
mandatory | It is the pattern that we want to check in the given string. |
$inputString |
mandatory | It is the string for which we want to search the given pattern. |
$matches |
optional | If this parameter is given, then the function stores the result of the matching process in it. |
$flags |
optional | This parameter has two options: PREG_OFFSET_CAPTURE and PREG_UNMATCHED_AS_NULL. You can read its description here. |
$offset |
optional | It tells the function of where to start the matching process. Usually, the search starts from the beginning. |
This function returns a boolean variable. It returns true if the given pattern exists. After extracting the numbers, we will print them in the required format.
The program below shows the way by which we can use PHP preg_match() function to format phone numbers.
<?php
$number = '+12333509234';
echo("The original number is $number.n");
if( preg_match( '/^+d(d{3})(d{3})(d{4})$/', $number, $matches ) )
{
$result = $matches[1] . '-' .$matches[2] . '-' . $matches[3];
}
echo("The formatted number is $result.");
?>
We have used /^+d(d{3})(d{3})(d{4})$/ pattern to extract numbers from the string. The explanation of this pattern is as follows.
^is the symbol to match the start of the string.+matches the+in the string.+is a special character in PHP to match one or more times of the preceding pattern. Therefore, we need to addbefore+to escape this special character.dis used to match the single digit number from 0-9.d{3}means that it will match three consecutive numbers.
Output:
The original number is +12333509234.
The formatted number is 233-350-9234.
Use the sprintf() Function to Format Phone Numbers in PHP
We can also use the sprintf() function to format phone numbers in PHP. This function gives several formatting patterns to format strings. We will extract the numbers using substr() function in several strings. After that, we will combine these strings in the required format using the sprintf() function. The correct syntax to use this function is as follows.
sprintf($formatString, $string1, $string2, ..., $stringN)
The sprintf() function accepts N+1 parameters. The detail of its parameters is as follows
| Parameters | Description | |
|---|---|---|
$formatString |
mandatory | It is the format that will be applied to the given string or strings. |
$string1, $string2, $stringN |
mandatory | It is the string that we want to format. At least one string is mandatory. |
The function returns the formatted string. We will use the format %s-%s-%s to combine the numeric strings. The program that combines two strings is as follows.
<?php
$number = '+12333509234';
echo("The original number is $number.n");
$result = sprintf("%s-%s-%s",
substr($number, 2, 3),
substr($number, 5, 3),
substr($number, 8));
echo("The formatted number is $result.");
?>
Output:
The original number is +12333509234.
The formatted number is 233-350-9234.
Here’s how I find valid 10-digit US phone numbers. At this point I’m assuming the user wants my content so the numbers themselves are trusted. I’m using in an app that ultimately sends an SMS message so I just want the raw numbers no matter what. Formatting can always be added later
//eliminate every char except 0-9
$justNums = preg_replace("/[^0-9]/", '', $string);
//eliminate leading 1 if its there
if (strlen($justNums) == 11) $justNums = preg_replace("/^1/", '',$justNums);
//if we have 10 digits left, it's probably valid.
if (strlen($justNums) == 10) $isPhoneNum = true;
Edit: I ended up having to port this to Java, if anyone’s interested. It runs on every keystroke so I tried to keep it fairly light:
boolean isPhoneNum = false;
if (str.length() >= 10 && str.length() <= 14 ) {
//14: (###) ###-####
//eliminate every char except 0-9
str = str.replaceAll("[^0-9]", "");
//remove leading 1 if it's there
if (str.length() == 11) str = str.replaceAll("^1", "");
isPhoneNum = str.length() == 10;
}
Log.d("ISPHONENUM", String.valueOf(isPhoneNum));
Here’s how I find valid 10-digit US phone numbers. At this point I’m assuming the user wants my content so the numbers themselves are trusted. I’m using in an app that ultimately sends an SMS message so I just want the raw numbers no matter what. Formatting can always be added later
//eliminate every char except 0-9
$justNums = preg_replace("/[^0-9]/", '', $string);
//eliminate leading 1 if its there
if (strlen($justNums) == 11) $justNums = preg_replace("/^1/", '',$justNums);
//if we have 10 digits left, it's probably valid.
if (strlen($justNums) == 10) $isPhoneNum = true;
Edit: I ended up having to port this to Java, if anyone’s interested. It runs on every keystroke so I tried to keep it fairly light:
boolean isPhoneNum = false;
if (str.length() >= 10 && str.length() <= 14 ) {
//14: (###) ###-####
//eliminate every char except 0-9
str = str.replaceAll("[^0-9]", "");
//remove leading 1 if it's there
if (str.length() == 11) str = str.replaceAll("^1", "");
isPhoneNum = str.length() == 10;
}
Log.d("ISPHONENUM", String.valueOf(isPhoneNum));
