在 PHP 中格式化电话号码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4708248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 14:04:48  来源:igfitidea点击:

Formatting Phone Numbers in PHP

phpphone-number

提问by NightMICU

I am working on an SMS appand need to be able to convert the sender's phone number from +11234567890to 123-456-7890so it can be compared to records in a MySQL database.

我正在开发一个SMS 应用程序,需要能够将发件人的电话号码从+11234567890 转换123-456-7890,以便可以将其与MySQL 数据库中的记录进行比较。

The numbers are stored in the latter format for use elsewhere on the site and I would rather not change that format as it would require modifying a lot of code.

这些数字以后一种格式存储,以便在网站的其他地方使用,我宁愿不更改该格式,因为它需要修改大量代码。

How would I go about this with PHP?

我将如何用 PHP 解决这个问题?

Thanks!

谢谢!

回答by Xeoncross

This is a US phone formatter that works on more versions of numbers than any of the current answers.

这是一种美国电话格式化程序,可以处理比任何当前答案都多的数字版本。

$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}).*~', '() -', $number). "\n";
}

And here is a breakdown of the 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 ")"

Updated: March 11, 2015 to use {0,7}instead of {,7}

更新时间:2015 年 3 月 11 日以{0,7}代替使用{,7}

回答by slier

$data = '+11234567890';

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

回答by Bryan Schoen

This function will format international (10+ digit), non-international (10 digit) or old school (7 digit) phone numbers. Any numbers other than 10+, 10 or 7 digits will remain unformatted.

此功能将格式化国际(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;
}

回答by Daniel Hepper

Assuming that your phone numbers always have this exact format, you can use this snippet:

假设您的电话号码始终采用这种精确格式,您可以使用以下代码段:

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

回答by likeitlikeit

Phone numbers are hard. For a more robust, international solution, I would recommend this well-maintained PHP portof Google's libphonenumberlibrary.

电话号码很难。对于更强大、更国际化的解决方案,我会推荐Google 的libphonenumber库的这个维护良好的 PHP 端口

Using it like this,

像这样使用它,

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
}

you will get the following output:

您将获得以下输出:

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

I'd recommend using the E164format for duplicate checks. You could also check whether the number is a actually mobile number or not (using PhoneNumberUtil::getNumberType()), or whether it's even a US number (using PhoneNumberUtil::getRegionCodeForNumber()).

我建议使用E164重复检查的格式。您还可以检查该号码是否是实际的手机号码(使用PhoneNumberUtil::getNumberType()),或者甚至是美国号码(使用PhoneNumberUtil::getRegionCodeForNumber())。

As a bonus, the library can handle pretty much any input. If you, for instance, choose to run 1-800-JETBLUEthrough the code above, you will get

作为奖励,该库几乎可以处理任何输入。例如,如果您选择运行1-800-JETBLUE上面的代码,您将获得

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

Neato.

尼托。

It works just as nicely for countries other than the US. Just use another ISO country code in the parse()argument.

它对美国以外的国家也同样有效。只需在parse()参数中使用另一个 ISO 国家/地区代码即可。

回答by skibulk

Here's my USA-only solution, with the area code as an optional component, required delimiter for the extension, and regex comments:

这是我的仅限美国的解决方案,区号作为可选组件,扩展所需的分隔符和正则表达式注释:

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

And here's the script to test it:

这是测试它的脚本:

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

回答by Zeromatik

Here's a simple function for formatting phone numbers with 7 to 10 digits in a more European (or Swedish?) manner:

这是一个简单的函数,用于以更欧洲(或瑞典?)的方式格式化 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})/', '  ', $num);
    elseif($len == 8) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{3})/', ' -  ', $num);
    elseif($len == 9) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{2})([0-9]{2})/', ' -   ', $num);
    elseif($len == 10) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{2})([0-9]{3})/', ' -   ', $num);

    return $num;
}

回答by Viktor Jarnheimer

Don't reinvent the wheel! Import this amazing library:
https://github.com/giggsey/libphonenumber-for-php

不要重新发明轮子!导入这个惊人的库: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);

It is based on Google's library for parsing, formatting, and validating international phone numbers: https://github.com/google/libphonenumber

它基于 Google 的用于解析、格式化和验证国际电话号码的库:https: //github.com/google/libphonenumber

回答by Ali Lown

I see this being possible using either some regex, or a few substr calls (assuming the input is always of that format, and doesn't change length etc.)

我认为这可以使用一些正则表达式或一些 substr 调用(假设输入始终是那种格式,并且不会改变长度等)

something like

就像是

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

should do it.

应该这样做。

回答by RobertPitt

Try something like:

尝试类似:

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

this would take a $number of 8881112222and convert to 888-111-2222. Hope this helps.

这将需要一个 $number8881112222并转换为888-111-2222. 希望这可以帮助。