Memformat Nomor Telepon dalam PHP

102

Saya sedang mengerjakan aplikasi SMS dan harus dapat mengonversi nomor telepon pengirim dari +11234567890 menjadi 123-456-7890 sehingga dapat dibandingkan dengan catatan dalam database MySQL .

Angka-angka disimpan dalam format terakhir untuk digunakan di tempat lain di situs dan saya lebih suka tidak mengubah format itu karena akan memerlukan banyak modifikasi kode.

Bagaimana saya melakukan ini dengan PHP?

Terima kasih!

NightMICU
sumber
13
ahhhhh .... NOOOO .... kenapa kamu menyimpan nomor telepon seperti itu !? sebagai tali? Buruk buruk buruk! Anda harus menyimpannya sebagai int besar ... lebih sedikit penyimpanan yang diperlukan, indeks lebih cepat, penyortiran lebih cepat
sethvargo
7
tidak terlalu menjadi masalah dengan menyimpan nomor telepon sebagai string (tidak dapat dihindari saat Anda perlu menyimpan +61 (0) 812345678) - tetapi menyimpan format tertentu agak cerdik (yaitu, pemisah) - sebaiknya lakukan pemformatan di lapisan presentasi, bukan di lapisan data.
HorusKol
3
@NightMICU - itu 100% cara yang salah untuk melakukan itu ... Anda harus menyimpan sebagai integer dan memiliki fungsi yang dapat digunakan kembali yang memformat untuk tampilan
sethvargo
228
Menyimpan nomor telepon sebagai bilangan bulat untuk menghemat ruang penyimpanan adalah ide yang buruk. Nomor telepon bukanlah angka dalam pengertian umum bahwa Anda akan menghitungnya. Saat Anda harus menyimpan nomor di luar format khusus AS di mana nomor tersebut dapat dimulai dengan 0, Anda akan menemui masalah. Lebih baik menyimpan informasi ini sebagai string.
Charles Sprayberry
2
@NightMICU Jika itu membuat Anda merasa lebih baik tentang menyimpan sebagai string bahkan Jon Skeet yang hebat mengatakan untuk tidak menyimpan sebagai bilangan bulat untuk masalah nol di depan. stackoverflow.com/a/3483166/746010
Charles Sprayberry

Jawaban:

109
$data = '+11234567890';

if(  preg_match( '/^\+\d(\d{3})(\d{3})(\d{4})$/', $data,  $matches ) )
{
    $result = $matches[1] . '-' .$matches[2] . '-' . $matches[3];
    return $result;
}
slier
sumber
Untuk menangkap kemungkinan spasi dan format lain dari nomor internasional: / ^ (\ +? \ D {1,2}?) [.-]? (? (\ D {3}))? [.-]? (\ D {3}) [.-]? (\ D {4}) $ /
TeckniX
3
@stoutie Anda salah, $ kecocokan [0] adalah keseluruhan teks pola yang cocok, maka Anda perlu untuk array_shift ($ kecocokan) sebelum menggunakannya seperti itu.
Alexandre Reis Ribeiro
Apakah lebih cepat memformat ini pada keluaran? Menggunakan sprintfatau `` printf``? Seseorang tolong jelaskan padaku. Saya bekerja dengan nomor telepon khusus AS dan tidak berpikir menjalankannya melalui fungsi keluaran menggunakan substring adalah metode terbaik.
Rafael
Saya pikir SO harus menyertakan suara negatif pada komentar. Komentar @Stoutie menyesatkan.
peterchaula
1
Saya minta maaf untuk diri saya yang lebih muda, sebelum hari tdd memposting komentar yang salah bertahun-tahun yang lalu. Saya berjanji untuk melakukan yang lebih baik di masa depan. Komentar yang Anda rujuk sepertinya telah dihapus. Semuanya baik-baik saja. Selamat berlibur.
Stoutie
164

Ini adalah formatter telepon AS yang bekerja pada lebih banyak versi nomor daripada jawaban saat ini.

$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";
}

Dan berikut adalah rincian regex:

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 ")"

Diperbarui: 11 Maret 2015 untuk digunakan {0,7}sebagai pengganti{,7}

Xeoncross
sumber
Bagaimana jika nomor telepon memiliki ekstensi?
SpYk3HH
1
Poin bagus - apakah kita memiliki beberapa contoh bagaimana ekstensi terlihat di seluruh dunia? Mungkin seperti itu ~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})(?:[ \D#\-]*(\d{3,6}))?.*~.
Xeoncross
1
Bagaimana jika pengguna situs web saya tidak mencantumkan kode area?
skibulk
Bisakah kita mendapatkan rincian tentang apa yang dilakukan berbagai bagian regex (seperti yang ditunjukkan di bawah ini dalam jawaban lain)? yaitu: (\d{3}) // 3 digits [\d]// karakter yang bukan digit
roberthuttinger
1
@WesleyMurch Tampaknya ada perubahan pencocokan ekspresi reguler yang sekarang {,7}harus diperbarui {0,7}. Saya telah memperbarui kodenya.
Xeoncross
55

Fungsi ini akan memformat nomor telepon internasional (10+ digit), non-internasional (10 digit) atau sekolah lama (7 digit). Angka apa pun selain 10+, 10 atau 7 digit akan tetap tidak diformat.

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;
}
Bryan Schoen
sumber
Ini bagus tapi saya hanya ingin menunjukkan bahwa tanda kurung di sekitar kode area menyiratkan nomor opsional. Sebagian besar wilayah hukum tidak lagi menganggap kode area opsional sehingga memisahkan dengan tanda hubung sederhana lebih akurat.
Vincent
30

Dengan asumsi bahwa nomor telepon Anda selalu memiliki format yang persis seperti ini, Anda dapat menggunakan cuplikan ini:

$from = "+11234567890";
$to = sprintf("%s-%s-%s",
              substr($from, 2, 3),
              substr($from, 5, 3),
              substr($from, 8));
Daniel Hepper
sumber
Cukup echo $ to var ... Love it, bekerja untuk saya, hanya prefek.
Samuel Ramzan
22

Nomor telepon sulit. Untuk solusi internasional yang lebih kuat, saya akan merekomendasikan port PHP libphonenumber Google yang terpelihara dengan baik ini perpustakaan .

Menggunakannya seperti ini,

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
}

Anda akan mendapatkan output berikut:

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

Saya akan merekomendasikan menggunakan E164format untuk pemeriksaan duplikat. Anda juga dapat memeriksa apakah nomor tersebut benar-benar nomor ponsel (menggunakan PhoneNumberUtil::getNumberType()), atau apakah itu bahkan nomor AS (menggunakan PhoneNumberUtil::getRegionCodeForNumber()).

Sebagai bonus, perpustakaan dapat menangani hampir semua masukan. Jika Anda, misalnya, memilih untuk menjalankan 1-800-JETBLUEkode di atas, Anda akan mendapatkan

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

Neato.

Ini bekerja dengan baik untuk negara selain AS. Cukup gunakan kode negara ISO lain dalam parse()argumen.

suka itu
sumber
2
Perpustakaan yang bagus, tetapi perhatikan bahwa itu adalah 37 MB dan 1500 file! Dalam kasus saya, saya memiliki sejumlah nomor telepon untuk diformat, jadi saya memutuskan untuk menambahkan number_formattedkolom di database saya dan memasukkan nomor yang diformat secara manual. Masih menggunakan libphonenumbersecara lokal untuk menghasilkan angka yang diformat, tetapi termasuk perpustakaan besar untuk proyek kecil saya hanya berlebihan.
Magnus W
9

Inilah solusi khusus AS saya, dengan kode area sebagai komponen opsional, pembatas yang diperlukan untuk ekstensi, dan komentar regex:

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;
}

Dan inilah script untuk mengujinya:

$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");
}
skibulk
sumber
5

Berikut adalah fungsi sederhana untuk memformat nomor telepon dengan 7 hingga 10 digit dengan cara yang lebih Eropa (atau Swedia?):

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;
}
Zeromatik
sumber
5

Jangan menemukan kembali roda! Impor perpustakaan luar biasa ini:
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);

Ini didasarkan pada perpustakaan Google untuk mengurai, memformat, dan memvalidasi nomor telepon internasional: https://github.com/google/libphonenumber

Viktor Jarnheimer
sumber
3
Saya pikir ini adalah jawaban yang valid, tetapi jika Anda ingin itu berguna sesuai standar Stack Overflow, maka Anda harus mengedit untuk menyertakan contoh penyelesaian masalah OP menggunakan perpustakaan daripada hanya berbagi tautan.
Alecg_O
1
Terima kasih @Alecg_O! Saya telah menambahkan sebuah contoh.
Viktor Jarnheimer
4

Saya melihat ini mungkin menggunakan beberapa regex, atau beberapa panggilan substr (dengan asumsi input selalu dalam format itu, dan tidak berubah panjang, dll.)

sesuatu seperti

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

harus melakukannya.

Ali Lown
sumber
4

Ini lebih cepat dari RegEx.

$input = "0987654321"; 

$output = substr($input, -10, -7) . "-" . substr($input, -7, -4) . "-" . substr($input, -4); 
echo $output;
Rishabh
sumber
1
Pendek dan manis (y).
rahim.nagori
2

Cobalah sesuatu seperti:

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

ini akan membutuhkan $ sejumlah 8881112222dan dikonversi ke 888-111-2222. Semoga ini membantu.

RobertPitt
sumber
1
Sumber saran Anda: hotscripts.com/forums/php/36805-php-format-phone-numbers.html . Str_replace '.'juga harus diperbarui ke '-', atau dihapus. Itu disertakan karena kasus penggunaan tertentu yang dihadapi - dengan sedikit usaha Anda dapat mengubahnya menjadi preg_replace('/\d{3}/', '$0-', substr($number, 2))dan menjawab pertanyaan secara langsung.
Iiridayn
2

Pilihan lain - mudah diperbarui untuk menerima format dari konfigurasi.

$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;
}
David H.
sumber
1

Semua,

Saya pikir saya memperbaikinya. Bekerja untuk file masukan saat ini dan memiliki 2 fungsi berikut untuk menyelesaikannya!

function format_phone_number:

        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

function 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

Perhatikan saya memiliki ini di lib kelas, jadi dengan demikian panggilan "self :: validate_phone_number" dari fungsi / metode pertama.

Perhatikan baris # 32 dari fungsi "validate_phone_number" tempat saya menambahkan:

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

untuk mendapatkan saya pengembalian palsu diperlukan jika bukan nomor telepon yang valid.

Masih perlu menguji ini terhadap lebih banyak data, tetapi mengerjakan data saat ini, dengan format saat ini dan saya menggunakan gaya '8' untuk kumpulan data khusus ini.

Juga saya mengomentari logika "ekstensi" karena saya terus-menerus mendapatkan kesalahan darinya, karena saya tidak memiliki info itu di data saya.

OldManRiver
sumber
1

ini membutuhkan 7, 10 dan 11 digit, menghapus karakter tambahan dan menambahkan tanda hubung dengan pergi dari kanan ke kiri melalui string. ubah tanda hubung menjadi spasi atau titik.

$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;
John Dul
sumber
1

Saya tahu OP meminta format 123-456-7890, tetapi, berdasarkan jawaban John Dul , saya mengubahnya untuk mengembalikan nomor telepon dalam format tanda kurung, misalnya (123) 456-7890. Yang ini hanya menangani angka 7 dan 10 digit.

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;
}
Andrew Tibbetts
sumber
1

Ini pendapat saya:

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

//  123-456-7890

The sscanffungsi mengambil sebagai parameter kedua format string menceritakannya bagaimana menafsirkan karakter dari string pertama. Dalam kasus ini, itu berarti 2 karakter ( %2c), 3 karakter, 3 karakter, 4 karakter.

Biasanya sscanffungsi tersebut juga akan menyertakan variabel untuk menangkap data yang diekstraksi. Jika tidak, data dikembalikan dalam array yang telah saya panggil $parts.

The printpernyataan output string interpolasi. $part[0]diabaikan.

Saya telah menggunakan fungsi serupa untuk memformat nomor telepon Australia.

Perhatikan bahwa dari perspektif menyimpan nomor telepon:

  • nomor telepon adalah string
  • data yang disimpan tidak boleh menyertakan pemformatan, seperti spasi atau tanda hubung
Manngo
sumber
Ini adalah solusi paling elegan dan mudah dibaca. CIUMAN. Gulir tidak lebih jauh jika string input Anda selalu mengikuti pola yang sama persis. Terima kasih atas tambahan ini.
Musa
1

Format Telepon Inggris Raya

Untuk aplikasi yang saya kembangkan, saya menemukan bahwa orang memasukkan nomor telepon mereka 'dengan benar' dari formulir yang dapat dibaca manusia, tetapi memasukkan berbagai karakter acak seperti '-' '/' '+44' dll. Masalahnya adalah aplikasi cloud itu yang perlu dibicarakan cukup spesifik tentang formatnya. Daripada menggunakan ekspresi reguler (bisa membuat frustasi bagi pengguna) saya membuat kelas objek yang memproses nomor yang dimasukkan ke dalam format yang benar sebelum diproses oleh modul ketekunan.

Format keluaran memastikan bahwa setiap perangkat lunak penerima menafsirkan keluaran sebagai teks daripada bilangan bulat (yang kemudian akan segera kehilangan nol di depan) dan formatnya konsisten dengan British Telecoms pedoman pemformatan angka - yang juga membantu daya ingat manusia dengan membagi bilangan panjang menjadi kelompok-kelompok kecil yang mudah diingat.


+441234567890 memproduksi (01234) 567 890
02012345678 memproduksi (020) 1234 5678
1923123456 memproduksi (01923 ) 123456 01923123456 memproduksi (01923)
123456 01923
halo ini teks123456 memproduksi (01923) 123 456

Signifikansi segmen pertukaran nomor - dalam tanda kurung - adalah bahwa di Inggris Raya, dan sebagian besar negara lain, panggilan antar nomor dalam pertukaran yang sama dapat dilakukan dengan mengabaikan segmen pertukaran. Ini tidak berlaku untuk nomor telepon seri 07, 08 dan 09.

Saya yakin ada solusi yang lebih efisien, tetapi yang ini terbukti sangat andal. Lebih banyak format dapat dengan mudah diakomodasi dengan menambahkan fungsi teleNum di bagian akhir.

Prosedur ini dipanggil dari skrip pemanggil

$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;
    }
}
Mike M0ITI
sumber
0

Ini untuk sambungan telepon rumah Inggris Raya tanpa Kode Negara

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;
}

Hasil:

2012345678
becomes
20 1234 5678
typocoder
sumber
0

Silakan lihat fungsi berbasis substr yang dapat mengubah format

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);
}
Yevgeniy Afanasyev
sumber
0

Periksa nomor telepon

$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;
}
toko mudah
sumber