PHP'de Telefon Numaralarını Biçimlendirme


103

Bir üzerinde çalışıyorum SMS uygulaması ve gönderen kişinin telefon numarasını dönüştürmek gerekiyor +11234567890 için 123-456-7890 bir kayıtların kıyasla böylece MySQL veritabanı .

Numaralar, sitenin başka bir yerinde kullanılmak üzere ikinci biçimde saklanır ve çok fazla kodun değiştirilmesini gerektireceğinden bu biçimi değiştirmeyi tercih etmem.

Bunu PHP ile nasıl yapacağım?

Teşekkürler!


13
ahhhhh .... HAYIR .... neden telefon numaralarını böyle saklıyorsun !? dizge olarak? Kötü, kötü, kötü! Bunları büyük
girişler olarak

7
telefon numaralarını dizeler olarak saklamakla ilgili bir sorun değil (+61 (0) 812345678 saklamanız gerektiğinde önlenemez) - ancak belirli bir format saklamak biraz tehlikelidir (yani ayırıcılar) - en iyisi biçimlendirme veri katmanı yerine sunum katmanında.
HorusKol

3
@NightMICU - bunu yapmanın% 100 yanlış yolu bu ... Bir tamsayı olarak depolamalısınız ve görüntüleme için biçimlendiren yeniden kullanılabilir bir işleve sahip
olmalısınız

231
Depolama alanından tasarruf etmek için telefon numaralarını tam sayı olarak saklamak korkunç bir fikirdir. Telefon numaraları, genel anlamda, üzerinde matematik yapacağınız sayılar değildir. Numaraların 0 ile başlayabildiği ABD'ye özgü bir formatın dışındaki numaraları kaydetmeniz gerektiği an sorunlarla karşılaşacaksınız. Bu bilgiyi bir dizge olarak saklamak daha iyidir.
Charles Sprayberry

2
@NightMICU Dizge olarak saklama konusunda kendinizi daha iyi hissettiriyorsa, harika Jon Skeet bile önde gelen sıfır sorunu için tamsayı olarak saklamamanızı söylüyor. stackoverflow.com/a/3483166/746010
Charles Sprayberry

Yanıtlar:


109
$data = '+11234567890';

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

1
Uluslararası sayıların olası boşluklarını ve diğer biçimlerini yakalamak için: / ^ (\ +? \ D {1,2}?) [.-]? (? (\ D {3}))? [.-]? (\ D {3}) [.-]? (\ D {4}) $ /
TeckniX

3
@stoutie yanılıyorsunuz, $ eşleşmeler [0] tüm eşleşen desen metnidir, bu şekilde kullanmadan önce array_shift ($ eşleşmeleri) yapmanız gerekir.
Alexandre Reis Ribeiro

Bunu çıktıda biçimlendirmek daha mı hızlı olur? Kullanılması sprintfveya `printf``? Lütfen birisi bana açıklasın. Yalnızca ABD telefon numaralarıyla çalışıyorum ve alt dizeyi kullanarak bunları bir çıktı işlevi aracılığıyla çalıştırmanın en iyi yöntem olduğunu düşünmüyorum.
Rafael

Bence SO, yorumlara olumsuz oylar eklemeli. @Stoutie'nin yorumu yanıltıcıdır.
peterchaula

2
Yıllar önce kendi kendime hatalı yorumlar gönderen daha genç, ön-tdd günüm için özür dilerim. Gelecekte daha iyisini yapacağıma söz veriyorum. Referans verdiğiniz yorum silinmiş görünüyor. Herşey iyi. Mutlu tatiller.
Stoutie

165

Bu, mevcut yanıtlardan daha fazla sayı sürümünde çalışan bir ABD telefon biçimlendiricisidir.

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

Ve burada normal ifadenin bir dökümü:

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

Güncelleme: 11 Mart 2015 {0,7}yerine kullanılacak{,7}


Telefon numarasının bir uzantısı varsa ne olur?
SpYk3HH

1
İyi bir nokta - uzantıların dünya çapında nasıl göründüğüne dair bazı örneklerimiz var mı? Proabaly gibi bir şey ~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})(?:[ \D#\-]*(\d{3,6}))?.*~.
Xeoncross

1
Ya web sitesi kullanıcılarım alan kodunu atladıysa?
skibulk

Normal ifadenin çeşitli bölümlerinin ne yaptığının bir dökümünü alabilir miyiz (aşağıda başka bir yanıtta gösterildiği gibi)? yani: (\d{3}) // 3 digits [\d]// rakam olmayan karakter
roberthuttinger

1
@WesleyMurch Normal ifade eşleşmesinde artık {,7}güncellenmesi gereken bir değişiklik var gibi görünüyor {0,7}. Kodu güncelledim.
Xeoncross

55

Bu işlev, uluslararası (10+ basamaklı), uluslararası olmayan (10 basamaklı) veya eski usul (7 basamaklı) telefon numaralarını biçimlendirecektir. 10+, 10 veya 7 basamak dışındaki sayılar biçimlendirilmemiş olarak kalacaktır.

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

Bu harika ancak alan kodunun etrafındaki parantezlerin isteğe bağlı sayıları ifade ettiğini belirtmek isterim. Çoğu yargı bölgesi artık alan kodunu isteğe bağlı olarak kabul etmemektedir, bu nedenle basit bir kısa çizgiyle ayırmak daha doğrudur.
Vincent

31

Telefon numaralarınızın her zaman tam olarak bu biçime sahip olduğunu varsayarsak, şu pasajı kullanabilirsiniz:

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

Sadece var olan $ 'ı tekrarlayın ... Bayıldım, benim için çalıştı sadece kaymakam.
Samuel Ramzan

22

Telefon numaraları zordur. Daha sağlam, uluslararası bir çözüm için, Google'ın libphonenumber kitaplığının bu iyi korunmuş PHP bağlantı noktasını tavsiye ederim .

Bunu böyle kullanmak,

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
}

aşağıdaki çıktıyı alacaksınız:

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

E164Yinelenen kontroller için biçimi kullanmanızı tavsiye ederim . Numaranın gerçekten bir cep telefonu numarası PhoneNumberUtil::getNumberType()olup olmadığını (kullanarak ) veya bir ABD numarası olup olmadığını (kullanarak PhoneNumberUtil::getRegionCodeForNumber()) da kontrol edebilirsiniz.

Bonus olarak, kütüphane hemen hemen her girdiyi halledebilir. Örneğin, 1-800-JETBLUEyukarıdaki kodu çalıştırmayı seçerseniz ,

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

Neato.

ABD dışındaki ülkeler için de aynı derecede iyi çalışıyor. Bağımsız parse()değişkende başka bir ISO ülke kodu kullanın .


2
Harika bir kütüphane, ancak 37 MB ve 1500 dosya olduğunu unutmayın! Benim durumumda, biçimlendirmem gereken sınırlı sayıda telefon numaram var, bu yüzden number_formattedveritabanıma bir sütun eklemeye ve biçimlendirilmiş numaraları manuel olarak girmeye karar verdim . Yine libphonenumberde biçimlendirilmiş sayıları oluşturmak için yerel olarak kullanıyorum , ancak küçük projem için bu kadar büyük bir kitaplık eklemek çok fazla.
Magnus W

9

İsteğe bağlı bir bileşen olarak alan kodu, uzantı için gerekli sınırlayıcı ve normal ifade açıklamaları ile yalnızca ABD için çözümüm:

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

Ve işte test etmek için komut dosyası:

$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

Aşağıda, 7 ila 10 basamaklı telefon numaralarını daha Avrupa (veya İsveççe?) Bir şekilde biçimlendirmek için basit bir işlev verilmiştir:

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

RegEx'ten daha hızlı.

$input = "0987654321"; 

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

1
Kısa ve tatlı (y).
rahim.nagori

5

Tekerleği yeniden icat etmeyin! Bu harika kitaplığı içe aktarın:
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);

Uluslararası telefon numaralarını ayrıştırmak, biçimlendirmek ve doğrulamak için Google'ın kitaplığını temel alır: https://github.com/google/libphonenumber


3
Bunun geçerli bir cevap olduğunu düşünüyorum, ancak Yığın Taşması standartlarına göre yararlı olmasını istiyorsanız, sadece bir bağlantıyı paylaşmak yerine kitaplığı kullanarak OP'nin problemini çözen bir örnek dahil etmek için düzenlemelisiniz.
Alecg_O

1
Teşekkürler @Alecg_O! Bir örnek ekledim.
Viktor Jarnheimer

4

Bunun bazı normal ifadeler veya birkaç alt çağrı kullanarak mümkün olduğunu görüyorum (girişin her zaman bu formatta olduğunu ve uzunluğunu değiştirmediğini varsayarsak).

gibi bir şey

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

yapmalı.


2

Şöyle bir şey dene:

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

bu bir $ sayı alır 8881112222ve 888-111-2222. Bu yardımcı olur umarım.


1
Önerinizin kaynağı: hotscripts.com/forums/php/36805-php-format-phone-numbers.html . Str_replace değeri '.'de güncellenmeli '-'veya kaldırılmalıdır. Karşılaşılan özel kullanım durumu nedeniyle dahil edildi - çok az çabayla onu dönüştürüp preg_replace('/\d{3}/', '$0-', substr($number, 2))soruyu doğrudan yanıtlayabilirdiniz.
Iiridayn

2

Başka bir seçenek - konfigürasyondan bir format almak için kolayca güncellenir.

$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

Herşey,

Sanırım düzelttim. Mevcut giriş dosyaları için çalışıyor ve bunu yapmak için aşağıdaki 2 işlevi var!

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

Dikkat edin, bunu bir sınıf kitaplığında buldum, dolayısıyla ilk işlevden / yöntemden "self :: validate_phone_number" çağrısı.

"Validate_phone_number" işlevinin 32 numaralı satırında şunu ekledim:

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

bana geçerli bir telefon numarası değilse, gerekli olan yanlış dönüşü almak için.

Yine de bunu daha fazla veriye karşı test etmem gerekiyor, ancak mevcut veriler üzerinde mevcut formatla çalışıyorum ve bu belirli veri grubu için stil '8' kullanıyorum.

Ayrıca sürekli olarak hatalar aldığım için "uzantı" mantığını yorumladım, verilerimde bu bilgilerin hiçbirine sahip olmadığımı görüyorum.


1

bu 7, 10 ve 11 basamak alır, ek karakterleri kaldırır ve dize boyunca sağdan sola giderek kısa çizgiler ekler. çizgiyi boşluk veya noktaya değiştirin.

$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

OP'nin 123-456-7890 biçimini istediğini biliyorum, ancak John Dul'un cevabına göre , telefon numarasını parantez biçiminde döndürecek şekilde değiştirdim, örneğin (123) 456-7890. Bu yalnızca 7 ve 10 basamaklı sayıları işler.

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

İşte benim almam:

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

//  123-456-7890

sscanfİşlevi ikinci parametre olarak nasıl ilk dizeden karakterleri yorumlamak için bildiren bir biçim dizesi sürer. Bu durumda 2 karakter ( %2c), 3 karakter, 3 karakter, 4 karakter anlamına gelir .

Normalde sscanfişlev, çıkarılan verileri yakalamak için değişkenler de içerir. Değilse, veri çağırdığım bir dizide döndürülür $parts.

printİfadesi enterpolasyonlu dizgisi verir. $part[0]dikkate alınmaz.

Avustralya telefon numaralarını biçimlendirmek için benzer bir işlev kullandım.

Telefon numarasını saklama açısından şunu unutmayın:

  • telefon numaraları dizedir
  • saklanan veriler gerekir olup bu boşluk veya çizgi olarak, biçimlendirme içerir

Bu en zarif ve okunabilir çözümdür. ÖPÜCÜK. Giriş dizeleriniz her zaman tam olarak aynı kalıbı izliyorsa daha fazla kaydırmayın. Bu ilave için teşekkür ederim.
Musa

1

Birleşik Krallık Telefon Biçimleri

Geliştirdiğim uygulama için, insanların telefon numaralarını insan tarafından okunabilir bir formdan 'doğru' olarak girdiklerini, ancak '-' '/' '+44' gibi çeşitli rastgele karakterler eklediklerini buldum. Sorun şu ki, format hakkında konuşulması gereken oldukça spesifikti. Normal bir ifade kullanmak yerine (kullanıcı için sinir bozucu olabilir) Kalıcılık modülü tarafından işlenmeden önce girilen sayıyı doğru biçimde işleyen bir nesne sınıfı yarattım.

Çıktının formatı, herhangi bir alıcı yazılımın çıktıyı bir tamsayı yerine metin olarak yorumlamasını (daha sonra baştaki sıfırı hemen kaybedecektir) ve formatın British Telecoms ile tutarlı olmasını sağlar. Sayı biçimlendirme yönergeleri - uzun bir sayıyı küçük, kolay ezberlenebilir gruplara bölerek insan hatırasına yardımcı olur.


+441234567890 (01234)
567890 02012345678 üretir (020) 1234 5678
1923123456 üretir (01923) 123 456
01923123456 üretir (01923) 123 456
01923 merhaba bu text123456 üretir (01923) 123 456

Numaranın değişim bölümünün önemi - parantez içinde - Birleşik Krallık'ta ve diğer birçok ülkede, aynı borsadaki numaralar arasındaki aramaların değişim segmenti çıkarılarak yapılabilmesidir. Ancak bu 07, 08 ve 09 serisi telefon numaraları için geçerli değildir.

Eminim daha verimli çözümler vardır, ancak bunun son derece güvenilir olduğu kanıtlanmıştır. Sonunda teleNum işlevine eklenerek daha fazla format kolayca yerleştirilebilir.

Prosedür çağıran komut dosyasından çağrılır, böylece

$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

Bu, Ülke Kodu bulunmayan Birleşik Krallık sabit hatları içindir

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

Sonuç:

2012345678
becomes
20 1234 5678

0

Lütfen formatları değiştirebilen substr tabanlı işleve bir göz atın

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

Telefon numarasını kontrol edin

$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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.