porcentaje - number_format php sin redondeo
Formatear números de teléfono en PHP (15)
Aquí está mi solución solo para EE. UU., Con el código de área como un componente opcional, el delimitador requerido para la extensión y los comentarios de expresiones regulares:
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;
}
Y aquí está el script para probarlo:
$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");
}
Estoy trabajando en una aplicación de SMS y necesito poder convertir el número de teléfono del remitente de +11234567890 a 123-456-7890 para que pueda ser comparado con los registros en una base de datos MySQL .
Los números se almacenan en el último formato para su uso en otro lugar del sitio y prefiero no cambiar ese formato, ya que requeriría modificar un montón de código.
¿Cómo voy a hacer esto con PHP?
¡Gracias!
Aquí hay una función simple para formatear números de teléfono con 7 a 10 dígitos de una manera más europea (¿o sueca?):
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;
}
Esta función formateará números de teléfono internacionales (más de 10 dígitos), no internacionales (10 dígitos) o de la vieja escuela (7 dígitos). Cualquier número que no sea de más de 10, 10 o 7 dígitos permanecerá sin formato.
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;
}
Este es un formateador de teléfono de EE. UU. Que funciona en más versiones de números que cualquiera de las respuestas actuales.
$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";
}
Y aquí está un desglose de la expresión regular:
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 ")"
Actualizado: 11 de marzo de 2015 para usar {0,7}
lugar de {,7}
Esto es para líneas fijas del Reino Unido sin el código de país
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;
}
Resultado:
2012345678
becomes
20 1234 5678
Los números de teléfono son difíciles. Para una solución internacional más robusta, recomendaría este puerto PHP bien mantenido de la biblioteca libphonenumber de Google.
Utilizándolo así,
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
}
obtendrá la siguiente salida:
Input: +12123456789
isValid: true
E164: +12123456789
National: (212) 345-6789
International: +1 212-345-6789
Recomiendo usar el formato E164
para verificaciones duplicadas. También puede verificar si el número es realmente un número de móvil o no (usando PhoneNumberUtil::getNumberType()
), o si es incluso un número de US (usando PhoneNumberUtil::getRegionCodeForNumber()
).
Como beneficio adicional, la biblioteca puede manejar casi cualquier entrada. Si, por ejemplo, elige ejecutar 1-800-JETBLUE
través del código anterior, obtendrá
Input: 1-800-JETBLUE
isValid: true
E164: +18005382583
National: (800) 538-2583
International: +1 800-538-2583
Neato.
Funciona igual de bien para otros países que no sean los EE. UU. Simplemente use otro código de país ISO en el argumento parse()
.
Otra opción: se actualiza fácilmente para recibir un formato de la configuración.
$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;
}
Pruebe algo como:
preg_replace(''//d{3}/'', ''$0-'', str_replace(''.'', null, trim($number)), 2);
esto tomaría un número de $ 8881112222
y convertiría a 888-111-2222
. Espero que esto ayude.
Sé que OP está solicitando un formato 123-456-7890, pero, según la respuesta de John Dul , lo modifiqué para devolver el número de teléfono entre paréntesis, por ejemplo, (123) 456-7890. Este solo maneja números de 7 y 10 dígitos.
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;
}
Suponiendo que sus números de teléfono siempre tengan este formato exacto, puede usar este fragmento:
$from = "+11234567890";
$to = sprintf("%s-%s-%s",
substr($from, 2, 3),
substr($from, 5, 3),
substr($from, 8));
Todas,
Creo que lo arreglé Trabajando para archivos de entrada actuales y teniendo las siguientes 2 funciones para hacer esto!
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
función 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
Tenga en cuenta que tengo esto en una clase lib, por lo tanto, la llamada "self :: validate_phone_number" de la primera función / método.
Observe la línea n. ° 32 de la función "validate_phone_number" donde agregué el:
if ( !$valid[''format''] ) {
return false;
} else {
para obtener la devolución falsa necesaria si no es un número de teléfono válido.
Todavía necesito probar esto con más datos, pero trabajando en datos actuales, con el formato actual y estoy usando el estilo ''8'' para este lote de datos en particular.
También comenté la lógica de "extensión" ya que constantemente obtenía errores, ya que no tengo información de eso en mis datos.
Veo que esto es posible usando algunas expresiones regulares, o algunas llamadas substr (suponiendo que la entrada siempre es de ese formato, y no cambia la duración, etc.)
algo como
$in = "+11234567890"; $output = substr($in,2,3)."-".substr($in,6,3)."-".substr($in,10,4);
Deberías hacerlo.
esto toma 7, 10 y 11 dígitos, elimina caracteres adicionales y agrega guiones yendo de derecha a izquierda a través de la cadena. cambia el tablero a un espacio o punto.
$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;
Es rápido que Reg-Ex.
$ input = "0987654321";
echo $ output = substr ($ input, -10, -7). "-". substr ($ input, -7, -4). "-". substr ($ input, -4);
$data = ''+11234567890'';
if( preg_match( ''/^/+/d(/d{3})(/d{3})(/d{4})$/'', $data, $matches ) )
{
$result = $matches[1] . ''-'' .$matches[2] . ''-'' . $matches[3];
return $result;
}