19

What is the best way to add dashes to a phone number in PHP? I have a number in the format xxxxxxxxxx and I want it to be in the format xxx-xxx-xxxx. This only applies to 10 digit US phone numbers.

Catfish
  • 18,876
  • 54
  • 209
  • 353

7 Answers7

51
$number = "1234567890";
$formatted_number = preg_replace("/^(\d{3})(\d{3})(\d{4})$/", "$1-$2-$3", $number);

EDIT: To be a bit more generic and normalize a US phone number given in any of a variety of formats (which should be common practice - there's no reason to force people to type in a phone number in a specific format, since all you're interested in are the digits and you can simply discard the rest):

function localize_us_number($phone) {
  $numbers_only = preg_replace("/[^\d]/", "", $phone);
  return preg_replace("/^1?(\d{3})(\d{3})(\d{4})$/", "$1-$2-$3", $numbers_only);
}

echo localize_us_number("5551234567"), "\n";
echo localize_us_number("15551234567"), "\n";
echo localize_us_number("+15551234567"), "\n";
echo localize_us_number("(555) 123-4567"), "\n";
echo localize_us_number("+1 (555) 123-4567"), "\n";
echo localize_us_number("Phone: 555 1234567 or something"), "\n";
Thilo
  • 17,565
  • 5
  • 68
  • 84
  • I did some tests and this is the fastest method – Galen May 03 '11 at 16:06
  • 1
    @Galen: be wary of absolutes like "Fastest". A faster solution then this is `$formatted = "$number[0]$number[1]$number[2]-$number[3] ...` til the string is done. – Erik May 03 '11 at 17:25
  • By fastest i meant fastest of the methods that were provided at that time – Galen May 03 '11 at 17:54
  • Fast shouldn't really matter here unless you plan on applying this to aproximately 4,567,138,234,234 phone numbers at a time. – Thilo May 03 '11 at 17:56
  • 1
    To take this a step further, prepare the pattern for an extension of an indefinite number of digits. $formatted_number = preg_replace("/^(\d{3})(\d{3})(\d{4})(\d{1,})$/", "$1-$2-$3-$4", $number); – Rivers Mar 03 '12 at 00:22
  • In my case, this worked out: **$formatted_number = preg_replace("/^(\d{3})(\d{7})$/", "$1-$2", $number);** – shasi kanth Dec 17 '13 at 07:50
  • Saved me tons of time! Thanks! – Radmation Oct 30 '18 at 16:44
11
$number = '1234567890';
if(ctype_digit($number) && strlen($number) == 10) {
  $number = substr($number, 0, 3) .'-'.
            substr($number, 3, 3) .'-'.
            substr($number, 6);
}

Or if you for some reason want to avoid substr:

$number = '1234567890';
if(ctype_digit($number) && strlen($number) == 10) {
  $parts = str_split($number, 3);
  $number = $parts[0] .'-'. $parts[1] .'-'. $parts[3].$parts[4];
}
Emil Vikström
  • 90,431
  • 16
  • 141
  • 175
1

iterate through the string and make counter. When counter is 3 or 7 insert dash.

nyanev
  • 11,299
  • 6
  • 47
  • 76
1

I feel obliged to post. Cheesiest solution:

$number = "1234567890";
$formatted_number = "$number[0]$number[1]$number[2]-$number[3]$number[4]$number[5]-$number[6]$number[7]$number[8]$number[9]";

But it works and its fast. vs. the preg_replace solution:

250,000 iterations:

preg_replace: 1.23 seconds ugly solution: 0.866 seconds

Pretty meaningless but fun :P

Erik
  • 20,526
  • 8
  • 45
  • 76
  • Now plug "foo" into your string. Poof. With preg_replace, all you get is the original string back if the regex doesn't match. I'd choose robustness vs speed here. :) – Thilo May 03 '11 at 17:58
  • oh i wasn't suggesting you USE the above code. I posted it really because of galen's comment, and it amused me. Your original question gave the assumption of a string of 10 digits, for which this works. You didn't say anything about validating it as a proper phone number. – Erik May 03 '11 at 18:00
  • Wasn't my question, just my answer. I'm just advocating defensive coding practices. – Thilo May 03 '11 at 18:16
  • to be honest, I didn't even know this solution was even possible. – Catfish May 03 '11 at 19:21
  • @thilo in most cases I would have answered very similarly to you. Actually I did: http://stackoverflow.com/questions/2315355/how-can-i-split-this-string-with-a-hyphen/2315377#2315377 months ago, to a nearly identical question. – Erik May 03 '11 at 19:41
0

Here's what I used. It's not perfect, but it's an improvement over @Thilo's answer. It checks for a leading 1. If it's there, it ignores it. The code also ignores separating dashes, commas, and spaces, so it will work with 1231231234, 123 123 1234, and 123.123.1234. It doesn't handle numbers with parenthesis, but I'm sure there's another thread out there with that solution!

$formatted_number = preg_replace("/^1?(?:[- .])?(\d{3})(?:[- .])?(\d{3})(?:[- .])?(\d{4})$/", "($1) $2-$3", $not_formatted_phone_number);
Zack Katz
  • 1,310
  • 11
  • 9
0

A modification of Thilo's answer providing complete conditional formatting control over the leading "1".

public function phoneFormat($number) {
        $numbersOnly = preg_replace("/[^\d]/", "", $number);
        $nums = array_filter(explode("-", preg_replace("/^(1|)(\d{3})(\d{3})(\d{4})$/",
                                                            "$1-$2-$3-$4", $numbersOnly)));
        $output = $numbersOnly;
        if(count($nums) == 3){
            $output = "($nums[1])-$nums[2]-$nums[3]";
        }elseif(count($nums) == 4){
            $output = "$nums[0]-($nums[1])-$nums[2]-$nums[3]";
        }
        return $output;
  }
yak27
  • 94
  • 8
-1

Here's what I came up with:

function format_phone($var_num) {
    $var_num = trim($var_num);
    $var_num = str_replace("(","",$var_num);
    $var_num = str_replace(")","",$var_num);
    $var_num = str_replace("-","",$var_num);
    $var_num = str_replace(" ","",$var_num);
    $var_num = str_replace(".","",$var_num);
    $var_num = substr($var_num, -10);
    $var_area_code = substr($var_num, 0, -7);
    $var_exchange = substr($var_num, 3, -4);
    $var_extention = substr($var_num, -4);
    $var_return = "{$var_area_code}-{$var_exchange}-{$var_extention}";
    return $var_return;
}

// Examples:
$phone_number = "1 (757) 555-1212";
// $phone_number = "17575551212";
// $phone_number = "(757) 555-1212";
// $phone_number = "757.555.1212";
echo "{$phone_number} = " . format_phone($phone_number);
AnarchyOutlaw
  • 163
  • 2
  • 6
  • preg (regular expressions) work much better than using str_replace – relipse Mar 28 '19 at 15:36
  • String Replace uses Reg Ex. The idea is to valilidate the 10 digit phone number the user enters into a form in whatever format. The funtion then removes any formatting the user puts in, leaving only the ten digtits, then displays the phone number is a specified format. – AnarchyOutlaw Mar 29 '19 at 19:43