我正在处理短信应用并且需要能够将发件人的电话号码从 +11234567890 转换为 123-456-7890 因此可以将其与 MySQL数据库中的记录进行比较。
这些数字以后一种格式存储,以便在网站的其他地方使用,我宁愿不改变这种格式,因为它需要修改大量代码。
我如何使用PHP进行此操作?
谢谢!
答案 0 :(得分:148)
这是一款美国手机格式化程序,可以处理比当前答案更多的数字版本。
$numbers = explode("\n", '(111) 222-3333
((111) 222-3333
1112223333
111 222-3333
111-222-3333
(111)2223333
+11234567890
1-8002353551
123-456-7890 -Hello!
+1 - 1234567890
');
foreach($numbers as $number)
{
print preg_replace('~.*(\d{3})[^\d]{0,7}(\d{3})[^\d]{0,7}(\d{4}).*~', '($1) $2-$3', $number). "\n";
}
以下是正则表达式的细分:
Cell: +1 999-(555 0001)
.* zero or more of anything "Cell: +1 "
(\d{3}) three digits "999"
[^\d]{0,7} zero or up to 7 of something not a digit "-("
(\d{3}) three digits "555"
[^\d]{0,7} zero or up to 7 of something not a digit " "
(\d{4}) four digits "0001"
.* zero or more of anything ")"
更新时间:2015年3月11日,使用{0,7}
代替{,7}
答案 1 :(得分:94)
$data = '+11234567890';
if( preg_match( '/^\+\d(\d{3})(\d{3})(\d{4})$/', $data, $matches ) )
{
$result = $matches[1] . '-' .$matches[2] . '-' . $matches[3];
return $result;
}
答案 2 :(得分:44)
此功能将格式化国际(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;
}
答案 3 :(得分:30)
假设您的电话号码始终具有此格式,您可以使用以下代码段:
$from = "+11234567890";
$to = sprintf("%s-%s-%s",
substr($from, 2, 3),
substr($from, 5, 3),
substr($from, 8));
答案 4 :(得分:17)
电话号码很难。对于更强大的国际解决方案,我建议使用此well-maintained PHP port Google libphonenumber库。
像这样使用它,
use libphonenumber\NumberParseException;
use libphonenumber\PhoneNumber;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
$phoneUtil = PhoneNumberUtil::getInstance();
$numberString = "+12123456789";
try {
$numberPrototype = $phoneUtil->parse($numberString, "US");
echo "Input: " . $numberString . "\n";
echo "isValid: " . ($phoneUtil->isValidNumber($numberPrototype) ? "true" : "false") . "\n";
echo "E164: " . $phoneUtil->format($numberPrototype, PhoneNumberFormat::E164) . "\n";
echo "National: " . $phoneUtil->format($numberPrototype, PhoneNumberFormat::NATIONAL) . "\n";
echo "International: " . $phoneUtil->format($numberPrototype, PhoneNumberFormat::INTERNATIONAL) . "\n";
} catch (NumberParseException $e) {
// handle any errors
}
您将获得以下输出:
Input: +12123456789
isValid: true
E164: +12123456789
National: (212) 345-6789
International: +1 212-345-6789
我建议使用E164
格式进行重复检查。您还可以检查该号码是否是实际的手机号码(使用PhoneNumberUtil::getNumberType()
),或者它是否是美国号码(使用PhoneNumberUtil::getRegionCodeForNumber()
)。
作为奖励,图书馆几乎可以处理任何输入。例如,如果您选择通过上面的代码运行1-800-JETBLUE
,那么您将获得
Input: 1-800-JETBLUE
isValid: true
E164: +18005382583
National: (800) 538-2583
International: +1 800-538-2583
NEATO。
对于美国以外的国家来说,它的效果非常好。只需在parse()
参数中使用另一个ISO国家/地区代码。
答案 5 :(得分:8)
这是我的仅限美国的解决方案,区号为可选组件,扩展名需要分隔符,以及正则表达式注释:
function formatPhoneNumber($s) {
$rx = "/
(1)?\D* # optional country code
(\d{3})?\D* # optional area code
(\d{3})\D* # first three
(\d{4}) # last four
(?:\D+|$) # extension delimiter or EOL
(\d*) # optional extension
/x";
preg_match($rx, $s, $matches);
if(!isset($matches[0])) return false;
$country = $matches[1];
$area = $matches[2];
$three = $matches[3];
$four = $matches[4];
$ext = $matches[5];
$out = "$three-$four";
if(!empty($area)) $out = "$area-$out";
if(!empty($country)) $out = "+$country-$out";
if(!empty($ext)) $out .= "x$ext";
// check that no digits were truncated
// if (preg_replace('/\D/', '', $s) != preg_replace('/\D/', '', $out)) return false;
return $out;
}
以下是测试它的脚本:
$numbers = [
'3334444',
'2223334444',
'12223334444',
'12223334444x5555',
'333-4444',
'(222)333-4444',
'+1 222-333-4444',
'1-222-333-4444ext555',
'cell: (222) 333-4444',
'(222) 333-4444 (cell)',
];
foreach($numbers as $number) {
print(formatPhoneNumber($number)."<br>\r\n");
}
答案 6 :(得分:4)
这是一个简单的功能,用于以更加欧洲(或瑞典语)的方式格式化7到10位数的电话号码:
function formatPhone($num) {
$num = preg_replace('/[^0-9]/', '', $num);
$len = strlen($num);
if($len == 7) $num = preg_replace('/([0-9]{2})([0-9]{2})([0-9]{3})/', '$1 $2 $3', $num);
elseif($len == 8) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{3})/', '$1 - $2 $3', $num);
elseif($len == 9) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{2})([0-9]{2})/', '$1 - $2 $3 $4', $num);
elseif($len == 10) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{2})([0-9]{3})/', '$1 - $2 $3 $4', $num);
return $num;
}
答案 7 :(得分:4)
我认为这可以使用一些正则表达式或一些子函数调用(假设输入始终是那种格式,并且不会改变长度等。)
类似
$in = "+11234567890"; $output = substr($in,2,3)."-".substr($in,6,3)."-".substr($in,10,4);
应该这样做。
答案 8 :(得分:2)
尝试类似:
preg_replace('/\d{3}/', '$0-', str_replace('.', null, trim($number)), 2);
这需要$ {$ 1}}并转换为8881112222
。希望这会有所帮助。
答案 9 :(得分:2)
另一个选项 - 轻松更新以从配置中接收格式。
$numbers = explode("\n", '(111) 222-3333
((111) 222-3333
1112223333
111 222-3333
111-222-3333
(111)2223333
+11234567890
1-8002353551
123-456-7890 -Hello!
+1 - 1234567890
');
foreach( $numbers AS $number ){
echo comMember_format::phoneNumber($number) . '<br>';
}
// ************************************************************************
// Format Phone Number
public function phoneNumber( $number ){
$txt = preg_replace('/[\s\-|\.|\(|\)]/','',$number);
$format = '[$1?$1 :][$2?($2):x][$3: ]$4[$5: ]$6[$7? $7:]';
if( preg_match('/^(.*)(\d{3})([^\d]*)(\d{3})([^\d]*)(\d{4})([^\d]{0,1}.*)$/', $txt, $matches) ){
$result = $format;
foreach( $matches AS $k => $v ){
$str = preg_match('/\[\$'.$k.'\?(.*?)\:(.*?)\]|\[\$'.$k.'\:(.*?)\]|(\$'.$k.'){1}/', $format, $filterMatch);
if( $filterMatch ){
$result = str_replace( $filterMatch[0], (!isset($filterMatch[3]) ? (strlen($v) ? str_replace( '$'.$k, $v, $filterMatch[1] ) : $filterMatch[2]) : (strlen($v) ? $v : (isset($filterMatch[4]) ? '' : (isset($filterMatch[3]) ? $filterMatch[3] : '')))), $result );
}
}
return $result;
}
return $number;
}
答案 10 :(得分:2)
不要重新发明轮子!导入这个惊人的库:
https://github.com/giggsey/libphonenumber-for-php
$defaultCountry = 'SE'; // Based on the country of the user
$phoneUtil = PhoneNumberUtil::getInstance();
$swissNumberProto = $phoneUtil->parse($phoneNumber, $defaultCountry);
return $phoneUtil->format($swissNumberProto, PhoneNumberFormat::INTERNATIONAL);
它基于Google的库,用于解析,格式化和验证国际电话号码: https://github.com/google/libphonenumber
答案 11 :(得分:2)
这是我的看法:
$phone='+11234567890';
$parts=sscanf($phone,'%2c%3c%3c%4c');
print "$parts[1]-$parts[2]-$parts[3]";
// 123-456-7890
sscanf
函数将格式字符串作为第二个参数,告诉它如何解释第一个字符串中的字符。在这种情况下,它表示2个字符(%2c
),3个字符,3个字符,4个字符。
通常,sscanf
函数还将包含用于捕获提取的数据的变量。如果没有,则将数据返回到我称为$parts
的数组中。
print
语句输出插值的字符串。 $part[0]
被忽略。
我使用了类似的功能来格式化澳大利亚电话号码。
请注意,从存储电话号码的角度来看:
答案 12 :(得分:1)
所有
我想我修好了。为当前输入文件工作,并有以下2个功能来完成这项工作!
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
功能validate_phone_number:
function validate_phone_number ( $phone ) {
/*********************************************************************/
/* Purpose: To determine if the passed string is a valid phone */
/* number following one of the establish formatting */
/* styles for phone numbers. This function also breaks */
/* a valid number into it's respective components of: */
/* 3-digit area code, */
/* 3-digit exchange code, */
/* 4-digit subscriber number */
/* and validates the number against 10 digit US NANPA */
/* guidelines. */
/*********************************************************************/
$format_pattern = '/^(?:(?:\((?=\d{3}\)))?(\d{3})(?:(?<=\(\d{3})\))'.
'?[\s.\/-]?)?(\d{3})[\s\.\/-]?(\d{4})\s?(?:(?:(?:'.
'(?:e|x|ex|ext)\.?\:?|extension\:?)\s?)(?=\d+)'.
'(\d+))?$/';
$nanpa_pattern = '/^(?:1)?(?(?!(37|96))[2-9][0-8][0-9](?<!(11)))?'.
'[2-9][0-9]{2}(?<!(11))[0-9]{4}(?<!(555(01([0-9]'.
'[0-9])|1212)))$/';
// Init array of variables to false
$valid = array('format' => false,
'nanpa' => false,
'ext' => false,
'all' => false);
//Check data against the format analyzer
if ( preg_match ( $format_pattern, $phone, $matchset ) ) {
$valid['format'] = true;
}
//If formatted properly, continue
//if($valid['format']) {
if ( !$valid['format'] ) {
return false;
} else {
//Set array of new components
$components = array ( 'ac' => $matchset[1], //area code
'xc' => $matchset[2], //exchange code
'sn' => $matchset[3] //subscriber number
);
// $components = array ( 'ac' => $matchset[1], //area code
// 'xc' => $matchset[2], //exchange code
// 'sn' => $matchset[3], //subscriber number
// 'xn' => $matchset[4] //extension number
// );
//Set array of number variants
$numbers = array ( 'original' => $matchset[0],
'stripped' => substr(preg_replace('[\D]', '', $matchset[0]), 0, 10)
);
//Now let's check the first ten digits against NANPA standards
if(preg_match($nanpa_pattern, $numbers['stripped'])) {
$valid['nanpa'] = true;
}
//If the NANPA guidelines have been met, continue
if ( $valid['nanpa'] ) {
if ( !empty ( $components['xn'] ) ) {
if ( preg_match ( '/^[\d]{1,6}$/', $components['xn'] ) ) {
$valid['ext'] = true;
} // end if if preg_match
} else {
$valid['ext'] = true;
} // end if if !empty
} // end if $valid nanpa
//If the extension number is valid or non-existent, continue
if ( $valid['ext'] ) {
$valid['all'] = true;
} // end if $valid ext
} // end if $valid
return $valid['all'];
} // end functon validate_phone_number
注意我在类lib中有这个,所以从第一个函数/方法调用“self :: validate_phone_number”。
注意“validate_phone_number”函数的第32行,其中我添加了:
if ( !$valid['format'] ) {
return false;
} else {
如果没有有效的电话号码,请告诉我错误的回复。
仍然需要针对更多数据进行测试,但是使用当前格式处理当前数据,并且我对此特定数据批次使用样式'8'。
此外,我注释掉了“扩展”逻辑,因为我不断从中获取错误,因为我的数据中没有任何信息。
答案 13 :(得分:1)
它比RegEx快。
$input = "0987654321";
$output = substr($input, -10, -7) . "-" . substr($input, -7, -4) . "-" . substr($input, -4);
echo $output;
答案 14 :(得分:1)
这需要7,10和11位数字,删除其他字符并通过字符串从右到左添加破折号。将短划线更改为空格或点。
$raw_phone = preg_replace('/\D/', '', $raw_phone);
$temp = str_split($raw_phone);
$phone_number = "";
for ($x=count($temp)-1;$x>=0;$x--) {
if ($x === count($temp) - 5 || $x === count($temp) - 8 || $x === count($temp) - 11) {
$phone_number = "-" . $phone_number;
}
$phone_number = $temp[$x] . $phone_number;
}
echo $phone_number;
答案 15 :(得分:1)
英国电话格式
对于我开发的应用程序,我发现人们从人类可以理解的形式“正确”输入了他们的电话号码,但是插入了各种随机字符,例如“-” /“ + 44”等。问题是它需要与之交谈的云应用非常详细地说明了格式。我创建了一个对象类,而不是使用正则表达式(可能使用户感到沮丧),该对象类将在持久性模块处理之前将输入的数字处理为正确的格式。
输出的格式可确保任何接收软件将输出解释为文本,而不是整数(整数将立即丢失前导零),并且格式与 British Telecoms 上的准则一致数字格式-通过将一个长的数字分成易于记忆的小数字,也有助于提高人们的记忆力。
+441234567890产生(01234)567890
02012345678生产(020)1234 5678
1923123456生产(01923)123456
01923123456生产(01923)123456
01923您好,这是text123456产生(01923)123456
该号码交换段的重要性(用括号括起来)是在英国和大多数其他国家/地区,可以在同一交换中拨打号码之间的电话,而忽略该交换段。 但这不适用于07、08和09系列电话号码。
我敢肯定会有更有效的解决方案,但是事实证明,这一解决方案非常可靠。通过在末尾添加teleNum功能,可以轻松容纳更多格式。
因此从调用脚本中调用该过程
$telephone = New Telephone;
$formattedPhoneNumber = $telephone->toIntegerForm($num)
`
<?php
class Telephone
{
public function toIntegerForm($num) {
/*
* This section takes the number, whatever its format, and purifies it to just digits without any space or other characters
* This ensures that the formatter only has one type of input to deal with
*/
$number = str_replace('+44', '0', $num);
$length = strlen($number);
$digits = '';
$i=0;
while ($i<$length){
$digits .= $this->first( substr($number,$i,1) , $i);
$i++;
}
if (strlen($number)<10) {return '';}
return $this->toTextForm($digits);
}
public function toTextForm($number) {
/*
* This works on the purified number to then format it according to the group code
* Numbers starting 01 and 07 are grouped 5 3 3
* Other numbers are grouped 3 4 4
*
*/
if (substr($number,0,1) == '+') { return $number; }
$group = substr($number,0,2);
switch ($group){
case "02" :
$formattedNumber = $this->teleNum($number, 3, 4); // If number commences '02N' then output will be (02N) NNNN NNNN
break;
default :
$formattedNumber = $this->teleNum($number, 5, 3); // Otherwise the ooutput will be (0NNNN) NNN NNN
}
return $formattedNumber;
}
private function first($digit,$position){
if ($digit == '+' && $position == 0) {return $digit;};
if (!is_numeric($digit)){
return '';
}
if ($position == 0) {
return ($digit == '0' ) ? $digit : '0'.$digit;
} else {
return $digit;
}
}
private function teleNum($number,$a,$b){
/*
* Formats the required output
*/
$c=strlen($number)-($a+$b);
$bit1 = substr($number,0,$a);
$bit2 = substr($number,$a,$b);
$bit3 = substr($number,$a+$b,$c);
return '('.$bit1.') '.$bit2." ".$bit3;
}
}
答案 16 :(得分:0)
这适用于没有国家/地区代码的英国固定电话
function format_phone_number($number) {
$result = preg_replace('~.*(\d{2})[^\d]{0,7}(\d{4})[^\d]{0,7}(\d{4}).*~', '$1 $2 $3', $number);
return $result;
}
结果:
2012345678
becomes
20 1234 5678
答案 17 :(得分:0)
我知道OP正在请求123-456-7890格式,但是,基于John Dul's answer,我修改了它以括号格式返回电话号码,例如(123)456-7890。这个只能处理7位和10位数字。
function format_phone_string( $raw_number ) {
// remove everything but numbers
$raw_number = preg_replace( '/\D/', '', $raw_number );
// split each number into an array
$arr_number = str_split($raw_number);
// add a dummy value to the beginning of the array
array_unshift( $arr_number, 'dummy' );
// remove the dummy value so now the array keys start at 1
unset($arr_number[0]);
// get the number of numbers in the number
$num_number = count($arr_number);
// loop through each number backward starting at the end
for ( $x = $num_number; $x >= 0; $x-- ) {
if ( $x === $num_number - 4 ) {
// before the fourth to last number
$phone_number = "-" . $phone_number;
}
else if ( $x === $num_number - 7 && $num_number > 7 ) {
// before the seventh to last number
// and only if the number is more than 7 digits
$phone_number = ") " . $phone_number;
}
else if ( $x === $num_number - 10 ) {
// before the tenth to last number
$phone_number = "(" . $phone_number;
}
// concatenate each number (possibly with modifications) back on
$phone_number = $arr_number[$x] . $phone_number;
}
return $phone_number;
}
答案 18 :(得分:0)
请查看可更改格式的基于substr的功能
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);
}
答案 19 :(得分:0)
检查电话号码
$phone = '+385 99 1234 1234'
$str = preg_match('/^\+?\d{1,3}[\s-]?\d{1,3}[\s-]?\d{1,4}[\s-]?\d{1,4}$/', $phone);
if($str){
return true;
}else{
return false;
}