Форматування телефонних номерів у PHP


102

Я працюю над додатком для SMS, і мені потрібно мати можливість перетворити номер телефону відправника з +11234567890 на 123-456-7890, щоб його можна було порівняти із записами в базі даних MySQL .

Номери зберігаються в останньому форматі для використання в іншому місці на сайті, і я б не хотів змінювати цей формат, оскільки для цього потрібно буде змінити багато коду.

Як би я пішов з цим на PHP?

Дякую!


13
Ааааа ... NOOOO .... чому ти зберігаєш такі телефонні номери !? як рядок? Погано погано погано! Ви повинні зберігати їх як великі вставки ... менше потрібного місця для зберігання, більш швидкого індексу, швидшого сортування
sethvargo

7
не стільки проблема із збереженням телефонних номерів, скільки рядків (неможливо уникнути, коли потрібно зберігати +61 (0) 812345678) - але зберігання певного формату дещо хитне (тобто сеператори) - найкраще робити форматування на рівні презентації, а не на рівні даних.
HorusKol

3
@NightMICU - це на 100% неправильний спосіб зробити це ... Ви повинні зберігати як ціле число і мати багаторазову функцію, яка форматується для відображення
sethvargo

228
Зберігання телефонних номерів як цілих чисел для економії місця в пам'яті - жахлива ідея. Номери телефонів - це не номери в загальному розумінні того, що ви будете на них рахувати. У той момент, коли вам доведеться зберігати номери за межами специфічного для США формату, де число може починатися з 0, у вас виникнуть проблеми. Краще зберігати цю інформацію як рядок.
Charles Sprayberry

2
@NightMICU Якщо змушує вас почувати себе краще як зберігати як рядок, навіть великий Джон Скіт говорить не зберігати як ціле число для провідної нульової проблеми. stackoverflow.com/a/3483166/746010
Чарльз Sprayberry

Відповіді:


109
$data = '+11234567890';

if(  preg_match( '/^\+\d(\d{3})(\d{3})(\d{4})$/', $data,  $matches ) )
{
    $result = $matches[1] . '-' .$matches[2] . '-' . $matches[3];
    return $result;
}

Для захоплення можливих пробілів та інших форматів міжнародних чисел: / ^ (\ +? \ D {1,2}?) [.-]? (? (\ D {3}))? [.-]? (\ D {3}) [.-]? (\ D {4}) $ /
TeckniX

3
@stoutie ви помиляєтеся, $ match [0] - це весь текст відповідного шаблону, тоді вам потрібно array_shift ($ match), перш ніж використовувати його таким чином.
Олександр Рейс Рібейро

Чи було б швидше відформатувати це на виході? Використання sprintfабо `printf``? Хтось, будь ласка, поясніть мені. Я працюю лише з телефонними номерами в США, і не думаю, що їх найкращий спосіб - запустити функцію виводу за допомогою підрядка.
Рафаель

Я думаю, що ТА повинен містити коментарі до коментарів. Коментар @Stoutie вводить в оману.
петершаула

1
Я прошу вибачення за молодший, перед тим, як самому розміщував помилкові коментарі стільки років тому. Обіцяю зробити краще в майбутньому. Здається, коментар, на який ви посилаєтесь, видалений. Все добре. Щасливих свят.
Stoutie

164

Це американський форматник телефону, який працює на більшій версії чисел, ніж будь-яка з поточних відповідей.

$numbers = explode("\n", '(111) 222-3333
((111) 222-3333
1112223333
111 222-3333
111-222-3333
(111)2223333
+11234567890
    1-8002353551
    123-456-7890   -Hello!
+1 - 1234567890 
');


foreach($numbers as $number)
{
    print preg_replace('~.*(\d{3})[^\d]{0,7}(\d{3})[^\d]{0,7}(\d{4}).*~', '($1) $2-$3', $number). "\n";
}

І ось розбиття регулярного вираження:

Cell: +1 999-(555 0001)

.*          zero or more of anything "Cell: +1 "
(\d{3})     three digits "999"
[^\d]{0,7}  zero or up to 7 of something not a digit "-("
(\d{3})     three digits "555"
[^\d]{0,7}  zero or up to 7 of something not a digit " "
(\d{4})     four digits "0001"
.*          zero or more of anything ")"

Оновлено: 11 березня 2015 року для використання {0,7}замість{,7}


Що робити, якщо номер телефону має розширення?
SpYk3HH

1
Добрий момент - чи є у нас приклади того, як розширення виглядають по всьому світу? Проабали щось подібне ~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})(?:[ \D#\-]*(\d{3,6}))?.*~.
Xeoncross

1
Що робити, якщо користувачі мого веб-сайту залишили код міста?
skibulk

Чи можемо ми отримати розбиття того, що роблять різні частини регулярного виразу (як показано нижче в іншій відповіді)? тобто: (\d{3}) // 3 digits [\d]// символ, який не є цифрою
roberthuttinger

1
@WesleyMurch Здається, змінюється відповідність регулярного виразу, до якого зараз потрібно {,7}оновити {0,7}. Я оновив код.
Xeoncross

55

Ця функція буде форматувати телефонні номери міжнародного (10+), неінтернаціонального (10 цифр) або старого шкільного (7 цифр). Будь-які цифри, окрім 10+, 10 або 7 цифр, залишаться неформатованими.

function formatPhoneNumber($phoneNumber) {
    $phoneNumber = preg_replace('/[^0-9]/','',$phoneNumber);

    if(strlen($phoneNumber) > 10) {
        $countryCode = substr($phoneNumber, 0, strlen($phoneNumber)-10);
        $areaCode = substr($phoneNumber, -10, 3);
        $nextThree = substr($phoneNumber, -7, 3);
        $lastFour = substr($phoneNumber, -4, 4);

        $phoneNumber = '+'.$countryCode.' ('.$areaCode.') '.$nextThree.'-'.$lastFour;
    }
    else if(strlen($phoneNumber) == 10) {
        $areaCode = substr($phoneNumber, 0, 3);
        $nextThree = substr($phoneNumber, 3, 3);
        $lastFour = substr($phoneNumber, 6, 4);

        $phoneNumber = '('.$areaCode.') '.$nextThree.'-'.$lastFour;
    }
    else if(strlen($phoneNumber) == 7) {
        $nextThree = substr($phoneNumber, 0, 3);
        $lastFour = substr($phoneNumber, 3, 4);

        $phoneNumber = $nextThree.'-'.$lastFour;
    }

    return $phoneNumber;
}

Це чудово, але я хотів би лише зазначити, що в дужках навколо коду області є необов’язкові числа. Більшість юрисдикцій вже не вважають код міста необов’язковим, тому розділення з простим дефісом є більш точним.
Вінсент

30

Якщо припустити, що ваші телефонні номери завжди мають такий точний формат, ви можете використовувати цей фрагмент:

$from = "+11234567890";
$to = sprintf("%s-%s-%s",
              substr($from, 2, 3),
              substr($from, 5, 3),
              substr($from, 8));

Просто перегукуйтесь на $ вар ... Любіть, працював на мене просто префект.
Самуель Рамзан

22

Номери телефонів важкі. Для більш надійного міжнародного рішення я б рекомендував цей доглянутий порт PHP бібліотеки Google Libphonenumber .

Використовуючи це так,

use libphonenumber\NumberParseException;
use libphonenumber\PhoneNumber;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;

$phoneUtil = PhoneNumberUtil::getInstance();

$numberString = "+12123456789";

try {
    $numberPrototype = $phoneUtil->parse($numberString, "US");

    echo "Input: " .          $numberString . "\n";
    echo "isValid: " .       ($phoneUtil->isValidNumber($numberPrototype) ? "true" : "false") . "\n";
    echo "E164: " .           $phoneUtil->format($numberPrototype, PhoneNumberFormat::E164) . "\n";
    echo "National: " .       $phoneUtil->format($numberPrototype, PhoneNumberFormat::NATIONAL) . "\n";
    echo "International: " .  $phoneUtil->format($numberPrototype, PhoneNumberFormat::INTERNATIONAL) . "\n";
} catch (NumberParseException $e) {
    // handle any errors
}

ви отримаєте такий вихід:

Input: +12123456789
isValid: true
E164: +12123456789
National: (212) 345-6789
International: +1 212-345-6789

Я рекомендую використовувати E164формат для дублювання чеків. Ви також можете перевірити, чи дійсно це номер мобільного телефону чи ні (використовуючи PhoneNumberUtil::getNumberType()), чи це навіть номер США (використовуючи PhoneNumberUtil::getRegionCodeForNumber()).

Як бонус, бібліотека може обробляти майже будь-які дані. Якщо ви, наприклад, вирішите пропустити 1-800-JETBLUEкод вище, ви отримаєте

Input: 1-800-JETBLUE
isValid: true
E164: +18005382583
National: (800) 538-2583
International: +1 800-538-2583

Неато.

Це працює так само чудово для інших країн, ніж США. Просто використовуйте інший код країни ISO в parse()аргументі.


2
Чудова бібліотека, але зауважте, що це 37 МБ і 1500 файлів! У моєму випадку у мене обмежена кількість телефонних номерів для форматування, тому я вирішив просто додати number_formattedстовпчик у свою базу даних і ввести вручну відформатовані номери. Все ще використовуйте libphonenumberлокально, щоб генерувати відформатовані номери, але включення такої величезної бібліотеки для мого невеликого проекту просто зайве.
Магнус Ш

9

Ось моє рішення, призначене лише для США, з кодом області як необов'язкового компонента, необхідним роздільником для розширення та коментарями регулярного вираження:

function formatPhoneNumber($s) {
$rx = "/
    (1)?\D*     # optional country code
    (\d{3})?\D* # optional area code
    (\d{3})\D*  # first three
    (\d{4})     # last four
    (?:\D+|$)   # extension delimiter or EOL
    (\d*)       # optional extension
/x";
preg_match($rx, $s, $matches);
if(!isset($matches[0])) return false;

$country = $matches[1];
$area = $matches[2];
$three = $matches[3];
$four = $matches[4];
$ext = $matches[5];

$out = "$three-$four";
if(!empty($area)) $out = "$area-$out";
if(!empty($country)) $out = "+$country-$out";
if(!empty($ext)) $out .= "x$ext";

// check that no digits were truncated
// if (preg_replace('/\D/', '', $s) != preg_replace('/\D/', '', $out)) return false;
return $out;
}

І ось сценарій для тестування:

$numbers = [
'3334444',
'2223334444',
'12223334444',
'12223334444x5555',
'333-4444',
'(222)333-4444',
'+1 222-333-4444',
'1-222-333-4444ext555',
'cell: (222) 333-4444',
'(222) 333-4444 (cell)',
];

foreach($numbers as $number) {
    print(formatPhoneNumber($number)."<br>\r\n");
}

5

Ось проста функція форматування телефонних номерів із 7 до 10 цифр більш європейським (чи шведським?) Способом:

function formatPhone($num) {
    $num = preg_replace('/[^0-9]/', '', $num);
    $len = strlen($num);

    if($len == 7) $num = preg_replace('/([0-9]{2})([0-9]{2})([0-9]{3})/', '$1 $2 $3', $num);
    elseif($len == 8) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{3})/', '$1 - $2 $3', $num);
    elseif($len == 9) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{2})([0-9]{2})/', '$1 - $2 $3 $4', $num);
    elseif($len == 10) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{2})([0-9]{3})/', '$1 - $2 $3 $4', $num);

    return $num;
}

5

Не винаходити колесо! Імпортуйте цю дивовижну бібліотеку:
https://github.com/giggsey/libphonenumber-for-php

$defaultCountry = 'SE'; // Based on the country of the user
$phoneUtil = PhoneNumberUtil::getInstance();
$swissNumberProto = $phoneUtil->parse($phoneNumber, $defaultCountry);

return $phoneUtil->format($swissNumberProto, PhoneNumberFormat::INTERNATIONAL);

Він заснований на бібліотеці Google для розбору, форматування та перевірки міжнародних телефонних номерів: https://github.com/google/libphonenumber


3
Я думаю, що це правильна відповідь, але якщо ви хочете, щоб вона була корисною за стандартами переповнення стека, тоді вам слід відредагувати, щоб включити приклад вирішення проблеми ОП за допомогою бібліотеки, а не просто обмін посиланням.
Alecg_O

1
Дякую @Alecg_O! Я додав приклад.
Віктор Ярхеймер

4

Я бачу, що це можливо, використовуючи або якийсь регулярний вираз, або кілька викликів substr (якщо при цьому вхід завжди має такий формат і не змінює довжину тощо)

щось на зразок

$in = "+11234567890"; $output = substr($in,2,3)."-".substr($in,6,3)."-".substr($in,10,4);

повинен це зробити.


4

Це швидше, ніж RegEx.

$input = "0987654321"; 

$output = substr($input, -10, -7) . "-" . substr($input, -7, -4) . "-" . substr($input, -4); 
echo $output;

1
Короткий і солодкий (у).
rahim.nagori

2

Спробуйте щось на кшталт:

preg_replace('/\d{3}/', '$0-', str_replace('.', null, trim($number)), 2);

для цього знадобиться $ 8881112222і перетворюється в 888-111-2222. Сподіваюся, це допомагає.


1
Джерело вашої пропозиції: hotscripts.com/forums/php/36805-php-format-phone-numbers.html . Str_replace '.'також слід оновити '-'або видалити. Він був включений через особливий випадок використання - з дуже малим зусиллям ви могли його перетворити preg_replace('/\d{3}/', '$0-', substr($number, 2))і відповісти на питання безпосередньо.
Iiridayn

2

Ще один варіант - легко оновлюється для отримання формату від конфігурації.

$numbers = explode("\n", '(111) 222-3333
((111) 222-3333
1112223333
111 222-3333
111-222-3333
(111)2223333
+11234567890
    1-8002353551
    123-456-7890   -Hello!
+1 - 1234567890
');
foreach( $numbers AS $number ){
  echo comMember_format::phoneNumber($number) . '<br>';
}

// ************************************************************************
// Format Phone Number
public function phoneNumber( $number ){
  $txt = preg_replace('/[\s\-|\.|\(|\)]/','',$number);
  $format = '[$1?$1 :][$2?($2):x][$3: ]$4[$5: ]$6[$7? $7:]';
  if( preg_match('/^(.*)(\d{3})([^\d]*)(\d{3})([^\d]*)(\d{4})([^\d]{0,1}.*)$/', $txt, $matches) ){
    $result = $format;
    foreach( $matches AS $k => $v ){
      $str = preg_match('/\[\$'.$k.'\?(.*?)\:(.*?)\]|\[\$'.$k.'\:(.*?)\]|(\$'.$k.'){1}/', $format, $filterMatch);
      if( $filterMatch ){
        $result = str_replace( $filterMatch[0], (!isset($filterMatch[3]) ? (strlen($v) ? str_replace( '$'.$k, $v, $filterMatch[1] ) : $filterMatch[2]) : (strlen($v) ? $v : (isset($filterMatch[4]) ? '' : (isset($filterMatch[3]) ? $filterMatch[3] : '')))), $result );
      }
    }
    return $result;
  }
  return $number;
}

1

Усі,

Я думаю, що я це виправив. Працюючи для поточних вхідних файлів і виконайте наступні 2 функції, щоб зробити це!

формат функції_фон_кілька:

        function format_phone_number ( $mynum, $mask ) {
        /*********************************************************************/
        /*   Purpose: Return either masked phone number or false             */
        /*     Masks: Val=1 or xxx xxx xxxx                                             */
        /*            Val=2 or xxx xxx.xxxx                                             */
        /*            Val=3 or xxx.xxx.xxxx                                             */
        /*            Val=4 or (xxx) xxx xxxx                                           */
        /*            Val=5 or (xxx) xxx.xxxx                                           */
        /*            Val=6 or (xxx).xxx.xxxx                                           */
        /*            Val=7 or (xxx) xxx-xxxx                                           */
        /*            Val=8 or (xxx)-xxx-xxxx                                           */
        /*********************************************************************/         
        $val_num        = self::validate_phone_number ( $mynum );
        if ( !$val_num && !is_string ( $mynum ) ) { 
            echo "Number $mynum is not a valid phone number! \n";
            return false;
        }   // end if !$val_num
        if ( ( $mask == 1 ) || ( $mask == 'xxx xxx xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '$1 $2 $3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 1
        if ( ( $mask == 2 ) || ( $mask == 'xxx xxx.xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '$1 $2.$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 2
        if ( ( $mask == 3 ) || ( $mask == 'xxx.xxx.xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '$1.$2.$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 3
        if ( ( $mask == 4 ) || ( $mask == '(xxx) xxx xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '($1) $2 $3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 4
        if ( ( $mask == 5 ) || ( $mask == '(xxx) xxx.xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '($1) $2.$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 5
        if ( ( $mask == 6 ) || ( $mask == '(xxx).xxx.xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '($1).$2.$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 6
        if ( ( $mask == 7 ) || ( $mask == '(xxx) xxx-xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '($1) $2-$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 7
        if ( ( $mask == 8 ) || ( $mask == '(xxx)-xxx-xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '($1)-$2-$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 8
        return false;       // Returns false if no conditions meet or input
    }  // end function format_phone_number

функція validate_phone_number:

        function validate_phone_number ( $phone ) {
        /*********************************************************************/
        /*   Purpose:   To determine if the passed string is a valid phone  */
        /*              number following one of the establish formatting        */
        /*                  styles for phone numbers.  This function also breaks    */
        /*                  a valid number into it's respective components of:      */
        /*                          3-digit area code,                                      */
        /*                          3-digit exchange code,                                  */
        /*                          4-digit subscriber number                               */
        /*                  and validates the number against 10 digit US NANPA  */
        /*                  guidelines.                                                         */
        /*********************************************************************/         
        $format_pattern =   '/^(?:(?:\((?=\d{3}\)))?(\d{3})(?:(?<=\(\d{3})\))'.
                                    '?[\s.\/-]?)?(\d{3})[\s\.\/-]?(\d{4})\s?(?:(?:(?:'.
                                    '(?:e|x|ex|ext)\.?\:?|extension\:?)\s?)(?=\d+)'.
                                    '(\d+))?$/';
        $nanpa_pattern      =   '/^(?:1)?(?(?!(37|96))[2-9][0-8][0-9](?<!(11)))?'.
                                    '[2-9][0-9]{2}(?<!(11))[0-9]{4}(?<!(555(01([0-9]'.
                                    '[0-9])|1212)))$/';

        // Init array of variables to false
        $valid = array('format' =>  false,
                            'nanpa' => false,
                            'ext'       => false,
                            'all'       => false);

        //Check data against the format analyzer
        if ( preg_match ( $format_pattern, $phone, $matchset ) ) {
            $valid['format'] = true;    
        }

        //If formatted properly, continue
        //if($valid['format']) {
        if ( !$valid['format'] ) {
            return false;
        } else {
            //Set array of new components
            $components =   array ( 'ac' => $matchset[1], //area code
                                                            'xc' => $matchset[2], //exchange code
                                                            'sn' => $matchset[3] //subscriber number
                                                            );
            //              $components =   array ( 'ac' => $matchset[1], //area code
            //                                              'xc' => $matchset[2], //exchange code
            //                                              'sn' => $matchset[3], //subscriber number
            //                                              'xn' => $matchset[4] //extension number             
            //                                              );

            //Set array of number variants
            $numbers    =   array ( 'original' => $matchset[0],
                                        'stripped' => substr(preg_replace('[\D]', '', $matchset[0]), 0, 10)
                                        );

            //Now let's check the first ten digits against NANPA standards
            if(preg_match($nanpa_pattern, $numbers['stripped'])) {
                $valid['nanpa'] = true;
            }

            //If the NANPA guidelines have been met, continue
            if ( $valid['nanpa'] ) {
                if ( !empty ( $components['xn'] ) ) {
                    if ( preg_match ( '/^[\d]{1,6}$/', $components['xn'] ) ) {
                        $valid['ext'] = true;
                    }   // end if if preg_match 
                } else {
                    $valid['ext'] = true;
                }   // end if if  !empty
            }   // end if $valid nanpa

            //If the extension number is valid or non-existent, continue
            if ( $valid['ext'] ) {
                $valid['all'] = true;
            }   // end if $valid ext
        }   // end if $valid
        return $valid['all'];
    }   // end functon validate_phone_number

Зверніть увагу, що я маю це у класі lib, тож виклик "self :: validate_phone_number" із першої функції / методу.

Помітьте рядок №32 функції "validate_phone_number", де я додав:

            if ( !$valid['format'] ) {
            return false;
        } else {

щоб отримати мені помилкове повернення, необхідне, якщо не дійсний номер телефону.

Ще потрібно перевірити це на більшій кількості даних, але працюю над поточними даними, у поточному форматі, і я використовую стиль "8" для цієї конкретної партії даних.

Також я прокоментував логіку "розширення", оскільки постійно отримував від неї помилки, бачачи, що я не маю жодної цієї інформації у своїх даних.


1

це займає 7, 10 та 11 цифр, видаляє додаткові символи та додає тире, рухаючись справа наліво через рядок. зміни тире на пробіл або крапку.

$raw_phone = preg_replace('/\D/', '', $raw_phone);
$temp = str_split($raw_phone);
$phone_number = "";
for ($x=count($temp)-1;$x>=0;$x--) {
    if ($x === count($temp) - 5 || $x === count($temp) - 8 || $x === count($temp) - 11) {
        $phone_number = "-" . $phone_number;
    }
    $phone_number = $temp[$x] . $phone_number;
}
echo $phone_number;

1

Я знаю, що ОП вимагає формату 123-456-7890, але, виходячи з відповіді Джона Дула , я змінив його, щоб повернути номер телефону у форматі дужок, наприклад (123) 456-7890. Цей лише обробляє 7 і 10 цифри.

function format_phone_string( $raw_number ) {

    // remove everything but numbers
    $raw_number = preg_replace( '/\D/', '', $raw_number );

    // split each number into an array
    $arr_number = str_split($raw_number);

    // add a dummy value to the beginning of the array
    array_unshift( $arr_number, 'dummy' );

    // remove the dummy value so now the array keys start at 1
    unset($arr_number[0]);

    // get the number of numbers in the number
    $num_number = count($arr_number);

    // loop through each number backward starting at the end
    for ( $x = $num_number; $x >= 0; $x-- ) {

        if ( $x === $num_number - 4 ) {
            // before the fourth to last number

            $phone_number = "-" . $phone_number;
        }
        else if ( $x === $num_number - 7 && $num_number > 7 ) {
            // before the seventh to last number
            // and only if the number is more than 7 digits

            $phone_number = ") " . $phone_number;
        }
        else if ( $x === $num_number - 10 ) {
            // before the tenth to last number

            $phone_number = "(" . $phone_number;
        }

        // concatenate each number (possibly with modifications) back on
        $phone_number = $arr_number[$x] . $phone_number;
    }

    return $phone_number;
}

1

Ось мій взяття:

$phone='+11234567890';
$parts=sscanf($phone,'%2c%3c%3c%4c');
print "$parts[1]-$parts[2]-$parts[3]";

//  123-456-7890

sscanfФункція приймає в якості другого параметра в рядок формату , кажучи йому , як інтерпретувати символи з першого рядка. У цьому випадку це означає 2 символи ( %2c), 3 символи, 3 символи, 4 символи.

Зазвичай sscanfфункція також включатиме змінні для захоплення вилучених даних. Якщо ні, дані повертаються в масив, який я викликав $parts.

Оператор printвиводить інтерпольований рядок. $part[0]ігнорується.

Я використовував подібну функцію для форматування австралійських телефонних номерів.

Зауважте, що з точки зору збереження номера телефону:

  • номери телефонів - це рядки
  • збережені дані не повинні включати форматування, наприклад пробіли або дефіси

Це найелегантніше і легше для читання рішення. KISS. Більше не прокручуйте, якщо вхідні рядки завжди відповідають точно такому ж шаблону. Дякую за це доповнення
Муса

1

Формати телефонів Великобританії

Для розробленого мною додатку я виявив, що люди вводили свій номер телефону `` правильно '' з зручної для читання форми, але вставляли різні випадкові символи, такі як '-' '/' '+44' тощо. Проблема полягала в тому, що хмарний додаток, який з якою потрібно було поговорити, було досить специфічно щодо формату. Замість того, щоб використовувати регулярний вираз (може бути розчаровуючим для користувача), я створив клас об’єктів, який обробляє введене число у правильний формат, перш ніж обробляти модуль збереження.

Формат виводу гарантує, що будь-яке програмне забезпечення, що приймає, інтерпретує результат як текст, а не ціле число (яке потім негайно втратить головний нуль) і формат узгоджується з British Telecoms вказівки щодо форматування чисел - які також сприяють запам'ятовуванню людини шляхом поділу довгого числа на невеликі групи, що легко запам'ятовуються.


+441234567890 виробляє (01234) 567 890
02012345678 виробляє (020) 1234 5678
1923123456 виробляє (01923) 123 456
01923123456 виробляє (01923) 123 456
01923helo це текст123456 виробляє (01923) 123 456

Значення біржового сегмента числа - в дужках - полягає в тому, що у Великобританії та більшості інших країн дзвінки між номерами в одній біржі можуть здійснюватися, опускаючи сегмент обміну. Однак це не стосується номерів телефонів серій 07, 08 та 09.

Я впевнений, що є більш ефективні рішення, але це виявилося надзвичайно надійним. Більше форматів можна легко розмістити, додавши до функції teleNum в кінці.

Процедура викликається таким чином із сценарію виклику

$telephone = New Telephone;
$formattedPhoneNumber = $telephone->toIntegerForm($num)

`

<?php
class   Telephone 
{   
    public function toIntegerForm($num) {
        /*
         * This section takes the number, whatever its format, and purifies it to just digits without any space or other characters
         * This ensures that the formatter only has one type of input to deal with
         */
        $number = str_replace('+44', '0', $num);
        $length = strlen($number);
        $digits = '';
        $i=0;
        while ($i<$length){
            $digits .= $this->first( substr($number,$i,1) , $i);
            $i++;
        }
        if (strlen($number)<10) {return '';}
        return $this->toTextForm($digits);
    }
    public function toTextForm($number) {

        /*
         * This works on the purified number to then format it according to the group code
         * Numbers starting 01 and 07 are grouped 5 3 3
         * Other numbers are grouped 3 4 4 
         * 
         */
        if (substr($number,0,1) == '+') { return $number; }
        $group = substr($number,0,2);
        switch ($group){
            case "02" :
                $formattedNumber = $this->teleNum($number, 3, 4); // If number commences '02N' then output will be (02N) NNNN NNNN
                break;
            default :
                $formattedNumber = $this->teleNum($number, 5, 3); // Otherwise the ooutput will be (0NNNN) NNN NNN
        }
        return $formattedNumber;

    }
    private function first($digit,$position){
        if ($digit == '+' && $position == 0) {return $digit;};
        if (!is_numeric($digit)){
            return '';
        }
        if ($position == 0) {
            return ($digit == '0' ) ? $digit :  '0'.$digit;
        } else {
            return $digit;
        } 
    }
    private function teleNum($number,$a,$b){
        /*
         * Formats the required output 
         */
        $c=strlen($number)-($a+$b);
        $bit1 = substr($number,0,$a);
        $bit2 = substr($number,$a,$b);
        $bit3 = substr($number,$a+$b,$c);
        return '('.$bit1.') '.$bit2." ".$bit3;
    }
}

0

Це для стаціонарних номерів Великобританії без Кодексу країни

function format_phone_number($number) {
    $result = preg_replace('~.*(\d{2})[^\d]{0,7}(\d{4})[^\d]{0,7}(\d{4}).*~', '$1 $2 $3', $number);
    return $result;
}

Результат:

2012345678
becomes
20 1234 5678

0

Перегляньте функцію на основі субстрату, яка може змінювати формати

function phone(string $in): string
{
    $FORMAT_PHONE = [1,3,3,4];
    $result =[];
    $position = 0;
    foreach ($FORMAT_PHONE as $key => $item){
        $result[] = substr($in, $position, $item);
        $position += $item;
    }
    return '+'.implode('-',$result);
}

0

Перевірте номер телефону

$phone = '+385 99 1234 1234'

$str = preg_match('/^\+?\d{1,3}[\s-]?\d{1,3}[\s-]?\d{1,4}[\s-]?\d{1,4}$/', $phone);

if($str){
return true;
}else{
return false;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.