Định dạng số điện thoại trong PHP


101

Tôi đang làm việc trên một ứng dụng SMS và cần có thể chuyển đổi số điện thoại của người gửi từ +11234567890 thành 123-456-7890 để có thể so sánh với các bản ghi trong cơ sở dữ liệu MySQL .

Các số được lưu trữ ở định dạng thứ hai để sử dụng ở những nơi khác trên trang web và tôi không muốn thay đổi định dạng đó vì nó sẽ yêu cầu sửa đổi rất nhiều mã.

Tôi sẽ làm thế nào về điều này với PHP?

Cảm ơn!


13
ahhhhh .... KHÔNG .... tại sao bạn lại lưu trữ số điện thoại như vậy !? như một chuỗi? Xấu xấu xấu! Bạn nên lưu trữ chúng như ints lớn ... ít lưu trữ cần thiết, nhanh hơn chỉ số, phân loại nhanh hơn
sethvargo

7
không có quá nhiều vấn đề với việc lưu trữ số điện thoại dưới dạng chuỗi (không thể tránh khỏi khi bạn cần lưu trữ +61 (0) 812345678) - nhưng việc lưu trữ một định dạng cụ thể là một chút khó hiểu (tức là các trình phân tách) - tốt nhất là nên định dạng ở lớp trình bày hơn là lớp dữ liệu.
HorusKol

3
@NightMICU - đó là 100% một cách sai lầm để làm điều đó ... Bạn nên được lưu trữ như một số nguyên và có chức năng tái sử dụng mà định dạng để hiển thị
sethvargo

227
Lưu trữ số điện thoại dưới dạng số nguyên để tiết kiệm không gian lưu trữ là một ý tưởng kinh khủng. Số điện thoại không phải là số theo nghĩa chung mà bạn sẽ làm toán trên chúng. Thời điểm bạn phải lưu trữ số bên ngoài định dạng cụ thể của Hoa Kỳ, nơi số có thể bắt đầu bằng số 0, bạn sẽ gặp phải vấn đề. Tốt hơn nên lưu trữ thông tin này dưới dạng chuỗi.
Charles Sprayberry

2
@NightMICU Nếu điều đó khiến bạn cảm thấy tốt hơn khi lưu trữ dưới dạng chuỗi, ngay cả Jon Skeet vĩ đại nói rằng không lưu trữ dưới dạng số nguyên cho bài toán số 0 hàng đầu. stackoverflow.com/a/3483166/746010
Charles Sprayberry

Câu trả lời:


108
$data = '+11234567890';

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

Để nắm bắt các khoảng trắng có thể có và các định dạng khác của số quốc tế: / ^ (\ +? \ D {1,2}?) [.-]? (? (\ D {3}))? [.-]? (\ D {3}) [.-]? (\ D {4}) $ /
TeckniX

3
@stoutie bạn nhầm rồi, $ phù hợp [0] là toàn bộ văn bản mẫu phù hợp, sau đó bạn cần phải array_shift ($ phù hợp) trước khi sử dụng theo cách đó.
Alexandre Reis Ribeiro

Nó sẽ nhanh hơn để định dạng này ở đầu ra? Sử dụng sprintfhay `printf ''? Ai đó làm ơn giải thích cho tôi. Tôi đang làm việc với các số điện thoại chỉ ở Hoa Kỳ và không nghĩ rằng chạy chúng thông qua một hàm đầu ra bằng cách sử dụng chuỗi con là phương pháp tốt nhất.
Rafael

Tôi nghĩ rằng SO nên bao gồm phiếu phản đối trên các bình luận. Bình luận của @Stoutie gây hiểu lầm.
peterchaula

1
Tôi xin lỗi vì tôi trẻ hơn, trước ngày tdd tự đăng những bình luận sai lầm nhiều năm trước. Tôi hứa sẽ làm tốt hơn trong tương lai. Nhận xét mà bạn tham khảo dường như đã bị xóa. Tất cả đều tốt. Những ngày lễ vui vẻ.
Stoutie

163

Đây là công cụ định dạng điện thoại của Hoa Kỳ hoạt động trên nhiều phiên bản số hơn bất kỳ câu trả lời hiện tại nào.

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

Và đây là bản phân tích của 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 ")"

Cập nhật: 11 tháng 3, 2015 để sử dụng {0,7}thay thế{,7}


Nếu số điện thoại có máy lẻ thì sao?
SpYk3HH

1
Điểm tốt - chúng tôi có một số ví dụ về cách tiện ích mở rộng trông như thế nào trên khắp thế giới không? Proabaly một cái gì đó giống như ~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})(?:[ \D#\-]*(\d{3,6}))?.*~.
Xeoncross

1
Điều gì sẽ xảy ra nếu người dùng trang web của tôi đã bỏ qua mã vùng?
skibulk

Chúng ta có thể phân tích những gì các phần khác nhau của regex đang làm (như được hiển thị bên dưới trong một câu trả lời khác) không? tức là: (\d{3}) // 3 digits [\d]// ký tự không phải là chữ số
roberthuttinger

1
@WesleyMurch Có vẻ như có một sự thay đổi mà đối sánh biểu thức chính quy hiện yêu cầu {,7}được cập nhật lên {0,7}. Tôi đã cập nhật mã.
Xeoncross

55

Chức năng này sẽ định dạng số điện thoại quốc tế (10+ chữ số), phi quốc tế (10 chữ số) hoặc số điện thoại cũ (7 chữ số). Bất kỳ số nào ngoài 10+, 10 hoặc 7 chữ số sẽ vẫn chưa được định dạng.

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

Điều này thật tuyệt nhưng tôi chỉ muốn chỉ ra rằng dấu ngoặc đơn xung quanh mã vùng ngụ ý các số tùy chọn. Hầu hết các khu vực pháp lý không còn coi mã vùng là tùy chọn vì vậy việc phân tách bằng dấu gạch ngang đơn giản sẽ chính xác hơn.
Vincent

30

Giả sử rằng số điện thoại của bạn luôn có định dạng chính xác này, bạn có thể sử dụng đoạn mã này:

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

Chỉ cần echo $ to var ... Yêu nó, làm việc cho tôi chỉ cần quận trưởng.
Samuel Ramzan

22

Số điện thoại thật khó. Để có một giải pháp quốc tế, mạnh mẽ hơn, tôi muốn giới thiệu cổng PHP được duy trì tốt này của thư viện libphonenumber của Google .

Sử dụng nó như thế này,

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
}

bạn sẽ nhận được kết quả sau:

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

Tôi khuyên bạn nên sử dụng E164định dạng để kiểm tra trùng lặp. Bạn cũng có thể kiểm tra xem số đó có phải là số điện thoại di động thực sự hay không (đang sử dụng PhoneNumberUtil::getNumberType()) hoặc thậm chí đó có phải là số của Hoa Kỳ (đang sử dụng PhoneNumberUtil::getRegionCodeForNumber()) hay không.

Như một phần thưởng, thư viện có thể xử lý khá nhiều đầu vào. Ví dụ: nếu bạn chọn chạy 1-800-JETBLUEqua đoạn mã trên, bạn sẽ nhận được

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

Neato.

Nó hoạt động hiệu quả đối với các quốc gia khác ngoài Hoa Kỳ. Chỉ cần sử dụng mã quốc gia ISO khác trong parse()đối số.


2
Thư viện tuyệt vời, nhưng lưu ý rằng nó là 37 MB và 1500 tệp! Trong trường hợp của tôi, tôi có một số lượng giới hạn số điện thoại để định dạng, vì vậy tôi quyết định chỉ thêm một number_formattedcột trong cơ sở dữ liệu của mình và nhập các số được định dạng theo cách thủ công. Tuy nhiên, vẫn sử dụng libphonenumbercục bộ để tạo các số được định dạng, nhưng bao gồm một thư viện khổng lồ như vậy cho dự án nhỏ của tôi là quá mức cần thiết.
Magnus W

9

Đây là giải pháp chỉ dành cho Hoa Kỳ của tôi, với mã vùng là thành phần tùy chọn, dấu phân cách bắt buộc cho tiện ích mở rộng và nhận xét 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;
}

Và đây là tập lệnh để kiểm tra nó:

$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

Đây là một chức năng đơn giản để định dạng số điện thoại có từ 7 đến 10 chữ số theo cách Châu Âu (hay Thụy Điển?) Hơn:

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

Đừng phát minh lại bánh xe! Nhập thư viện tuyệt vời này:
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);

Nó dựa trên thư viện của Google để phân tích cú pháp, định dạng và xác thực số điện thoại quốc tế: https://github.com/google/libphonenumber


3
Tôi nghĩ đây là một câu trả lời hợp lệ, nhưng nếu bạn muốn nó hữu ích theo tiêu chuẩn Stack Overflow, thì bạn nên chỉnh sửa để đưa vào một ví dụ giải quyết vấn đề của OP bằng cách sử dụng thư viện thay vì chỉ chia sẻ một liên kết.
Alecg_O

1
Xin cảm ơn @Alecg_O! Tôi đã thêm một ví dụ.
Viktor Jarnheimer

4

Tôi thấy điều này có thể thực hiện được bằng cách sử dụng một số lệnh regex hoặc một số lệnh phụ (giả sử đầu vào luôn có định dạng đó và không thay đổi độ dài, v.v.)

cái gì đó như

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

Hãy làm nó.


4

Nó nhanh hơn RegEx.

$input = "0987654321"; 

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

1
Ngắn gọn và ngọt ngào (y).
rahim.nagori

2

Hãy thử một cái gì đó như:

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

điều này sẽ mất một số $ 8881112222và chuyển đổi thành 888-111-2222. Hi vọng điêu nay co ich.


1
Nguồn gợi ý của bạn: hotscripts.com/forums/php/36805-php-format-phone-numbers.html . Str_replace của '.'cũng nên được cập nhật '-'hoặc loại bỏ. Nó đã được đưa vào vì trường hợp sử dụng cụ thể phải đối mặt - với rất ít nỗ lực, bạn có thể chuyển đổi nó thành preg_replace('/\d{3}/', '$0-', substr($number, 2))và trả lời câu hỏi trực tiếp.
Iiridayn

2

Một tùy chọn khác - dễ dàng cập nhật để nhận định dạng từ cấu hình.

$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

Tất cả,

Tôi nghĩ rằng tôi đã sửa nó. Làm việc với các tệp đầu vào hiện tại và có 2 chức năng sau để hoàn thành việc này!

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

Lưu ý rằng tôi có điều này trong một lib lớp, vì vậy lệnh gọi "self :: validate_phone_number" từ hàm / phương thức đầu tiên.

Thông báo dòng # 32 của hàm "validate_phone_number" nơi tôi đã thêm:

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

để yêu cầu tôi trả lại sai nếu số điện thoại không hợp lệ.

Vẫn cần kiểm tra điều này với nhiều dữ liệu hơn, nhưng đang làm việc trên dữ liệu hiện tại, với định dạng hiện tại và tôi đang sử dụng kiểu '8' cho lô dữ liệu cụ thể này.

Ngoài ra, tôi đã nhận xét logic "tiện ích mở rộng" vì tôi liên tục nhận được lỗi từ nó, vì tôi không có bất kỳ thông tin nào trong dữ liệu của mình.


1

điều này có 7, 10 và 11 chữ số, loại bỏ các ký tự bổ sung và thêm dấu gạch ngang bằng cách đi từ phải sang trái qua chuỗi. thay đổi dấu gạch ngang thành dấu cách hoặc dấu chấm.

$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

Tôi biết OP đang yêu cầu định dạng 123-456-7890, nhưng dựa trên câu trả lời của John Dul , tôi đã sửa đổi nó để trả về số điện thoại ở định dạng dấu ngoặc đơn, ví dụ: (123) 456-7890. Cái này chỉ xử lý các số 7 và 10 chữ số.

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

Đây là cách của tôi:

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

//  123-456-7890

Các sscanfchức năng mất như một tham số thứ hai là một chuỗi định dạng nói cho nó làm thế nào để giải thích các ký tự từ chuỗi đầu tiên. Trong trường hợp này, nó có nghĩa là 2 ký tự ( %2c), 3 ký tự, 3 ký tự, 4 ký tự.

Thông thường, sscanfhàm cũng sẽ bao gồm các biến để thu thập dữ liệu được trích xuất. Nếu không, dữ liệu được trả về trong một mảng mà tôi đã gọi $parts.

Câu printlệnh xuất ra chuỗi nội suy. $part[0]bị bỏ qua.

Tôi đã sử dụng một chức năng tương tự để định dạng số điện thoại Úc.

Lưu ý rằng từ góc độ lưu trữ số điện thoại:

  • số điện thoại là chuỗi
  • dữ liệu được lưu trữ không được bao gồm định dạng, chẳng hạn như dấu cách hoặc dấu gạch nối

Đây là giải pháp thanh lịch và dễ đọc nhất. HÔN. Không cuộn thêm nếu chuỗi nhập của bạn luôn theo cùng một mẫu. Cảm ơn bạn đã bổ sung này.
Musa

1

Định dạng điện thoại Vương quốc Anh

Đối với ứng dụng tôi đã phát triển, tôi thấy rằng mọi người đã nhập số điện thoại của họ 'chính xác' từ một biểu mẫu con người có thể đọc được, nhưng lại chèn các ký tự ngẫu nhiên khác nhau như '-' '/' '+44', v.v. Vấn đề là ứng dụng đám mây nó cần nói chuyện khá cụ thể về định dạng. Thay vì sử dụng một biểu thức chính quy (có thể gây khó chịu cho người dùng), tôi đã tạo một lớp đối tượng để xử lý số đã nhập thành định dạng chính xác trước khi được xử lý bởi mô-đun kiên trì.

Định dạng của đầu ra đảm bảo rằng bất kỳ phần mềm nhận nào cũng hiểu đầu ra là văn bản chứ không phải là số nguyên (sau đó sẽ mất ngay số 0 ở đầu) và định dạng phù hợp với Viễn thông Anh hướng dẫn về định dạng số - cũng hỗ trợ khả năng ghi nhớ của con người bằng cách chia một số dài thành các nhóm nhỏ, dễ ghi nhớ.


+441234567890 sản xuất (01234) 567 890
02012345678 sản xuất (020) 1234 5678
1923123456 sản xuất (01923) 123 456
01923123456 sản xuất (01923) 123 456
01923hello đây là văn bản123456 sản xuất (01923) 123 456

Ý nghĩa của phân đoạn trao đổi của số - trong ngoặc đơn - là ở Anh và hầu hết các quốc gia khác, các cuộc gọi giữa các số trong cùng một trao đổi có thể được thực hiện bỏ qua phân đoạn trao đổi. Tuy nhiên, điều này không áp dụng cho các số điện thoại dòng 07, 08 và 09.

Tôi chắc rằng có nhiều giải pháp hiệu quả hơn, nhưng giải pháp này đã được chứng minh là cực kỳ đáng tin cậy. Có thể dễ dàng chứa nhiều định dạng hơn bằng cách thêm vào chức năng teleNum ở cuối.

Do đó, thủ tục được gọi từ tập lệnh gọi

$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

Điều này dành cho điện thoại cố định của Vương quốc Anh không có Mã quốc gia

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

Kết quả:

2012345678
becomes
20 1234 5678

0

Hãy xem hàm dựa trên substr có thể thay đổi định dạng

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

Kiểm tra số điện thoại

$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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.