I need to find 10-digit phone numbers in a string, but I can't for the life of me figure out how to use preg_replace() properly so if someone could help me get the proper usage of it that would be great. I need to be able to search for number formats such as "5085551234", "508.555.1234", "508-555-1234", and "(508)-555-1234". Could someone help me get the command for this? Thanks, ~Thorlax
<?php $string = '(508)-555-1234'; $format_one.= '\d{10}'; //5085551234 $format_two_and_three .= '\d{3}(\.|\-)\d{3}\2\d{4}'; //508.555.1234 or 508-555-1234 $format_four .= '\(\d{3}\)\-\d{3}\-\d{4}'; //(508)-555-1234 $string = preg_replace("~({$format_one}|{$format_two_and_three}|{$format_four})~", 'The number -> $1 <-', $string); echo $string; ?> PHP:
Maybe this is what you want: $phone_number_raw = '123.456.7890'; $phone_number = preg_replace('\D', '', $phone_number_raw); PHP:
This might seem long winded but what the heck, you might find some of it useful and it will keep your records tidy. 1, the string is converted to blocks of 10digit numbers 2, we find all the blocks 3, we format the numbers in to US Area Prefix Number (800)-555-5555 <?php $string = "Because your page/string might be like this with text in between the numbers 5000001234 or 501.111.1111 or 502-222-2222 and (503)-333-3333"; $string = preg_replace("#[^\d{10}\s]#",'',$string); preg_match_all("#(\d{10})#", "$string", $found); function format_number($phone){ if(strlen($phone) != 10) return(False); $area = substr($phone,0,3); $prefix = substr($phone,3,3); $number = substr($phone,6,4); $phone = "(".$area.")-".$prefix."-".$number; return($phone); } foreach ($found as $phone_number) { $number1 = format_number($phone_number[0]); $number2 = format_number($phone_number[1]); $number3 = format_number($phone_number[2]); $number4 = format_number($phone_number[3]); } $numbers = "".$number1." ".$number2." ".$number3." ".$number4; echo $numbers; ?> PHP: OUT-PUT: (500)-000-1234 (501)-111-1111 (502)-222-2222 (503)-333-3333 Code (markup): Please note for this, I didn't bother adding foreach as a key which would have made the code smaller, but you get the idea.
Since it is now looking like I need all the numbers in the same format, then this looks like this could be a good option, but how would I edit this so that it doesn't simply return the numbers. I need them to stay in their appropriate locations in the string, but I also need to put xml tags around them.
So replace the numbers in the string, with the format of (503)-333-3333 and then return the hole string, is that what you mean ?
Yes, I will need the output to be the same as the original string, but I need all the numbers to return like this: <say-as interpret-as="vxml:phone"> 503.555.1234 </say-as> Code (markup): Basically I need to convert the number format to having periods between the parts and I need that tag around it. Also if it's not too much trouble, do you mind explaining the pattern recognition you use? I have never been able to figure out how to create patterns for use with the "preg" functions. Thanks.
Here you go... formats the numbers - 508.555.1234 with your tag around them, thanks to @Dan <?php $string = "Because your page/string might be like this with text in between the numbers 5000001234 or 501.111.1111 or 502-222-2222 and (503)-333-3333"; function format_number($phone){ $phone = preg_replace("#[^\d{10}\s]#",'',$phone); if(strlen($phone) != 10) return(False); $area = substr($phone,0,3); $prefix = substr($phone,3,3); $number = substr($phone,6,4); $format = "".$area.".".$prefix.".".$number; $phone = "<say-as interpret-as=\"vxml:phone\">$format</say-as>"; return($phone); } $format_one.= '\d{10}'; //5085551234 $format_two_and_three .= '\d{3}(\.|\-)\d{3}\2\d{4}'; //508.555.1234 or 508-555-1234 $format_four .= '\(\d{3}\)\-\d{3}\-\d{4}'; //(508)-555-1234 $string = preg_replace("~({$format_one}|{$format_two_and_three}|{$format_four})~e", 'format_number("$1")', $string); echo $string; ?> PHP: OUT-PUT: Because your page/string might be like this with text in between the numbers 500.000.1234 or 501.111.1111 or 502.222.2222 and 503.333.3333 Code (markup): SOURCE: Because your page/string might be like this with text in between the numbers <say-as interpret-as="vxml:phone">500.000.1234</say-as> or <say-as interpret-as="vxml:phone">501.111.1111</say-as> or <say-as interpret-as="vxml:phone">502.222.2222</say-as> and <say-as interpret-as="vxml:phone">503.333.3333</say-as> Code (markup):
I need the numbers in the format of "800.555.1234". Seems to be the only one the interpreter works properly with.
This line causes some problems: $string = preg_replace("~({$format_one}|{$format_two_and_three}|{$format_four})~e", 'format_number("$1")', $string); PHP: The format_number function doesn't execute with the quotes around it, but without the quotes then it tries to perform the function with a passed variable of value "$1". It fails to recognize $1 as a variable.
Not sure what you want, but the following code would strip all formatting and convert them all to format one? <?php $string = 'Because your page/string might be like this with text in between the numbers 5000001234 or 501.111.1111 or 502-222-2222 and (503)-333-3333'; function stripFormatting($match) { return preg_replace('~[^\d]~', NULL, $match[1]); } $format_one = '\d{10}'; //5085551234 $format_two_and_three = '\d{3}(\.|\-)\d{3}\2\d{4}'; //508.555.1234 or 508-555-1234 $format_four = '\(\d{3}\)\-\d{3}\-\d{4}'; //(508)-555-1234 $string = preg_replace_callback("~({$format_one}|{$format_two_and_three}|{$format_four})~", 'stripFormatting', $string); echo $string; ?> PHP: Is that what you want?
@danx10: What i need is to have them all formatted the same way and have an xml tag around them (as stated above). I'm not sure, but from the looks of this code then the function created doesn't get used. Looks like it replaces all the phone numbers with the string "stripFormatting". @myvodaphone I get the string "format_number("5085551234")" as a result. Weird...
I suggest you lookup the documenation on preg_replace_callback(), it calls the specified function (in this case stripFormatting) using the $array (in this case $match) of matches as the parameter. Theirfore the code I posted will work as it will format all the numbers the same way (as format one). Just one minor adjustment to wrap an xml tag around it though: <?php $string = 'Because your page/string might be like this with text in between the numbers 5000001234 or 501.111.1111 or 502-222-2222 and (503)-333-3333'; function stripFormatting($match) { //change the xml tag accordingly... return '<xml>'.preg_replace('~[^\d]~', NULL, $match[1]).'</xml>'; } $format_one = '\d{10}'; //5085551234 $format_two_and_three = '\d{3}(\.|\-)\d{3}\2\d{4}'; //508.555.1234 or 508-555-1234 $format_four = '\(\d{3}\)\-\d{3}\-\d{4}'; //(508)-555-1234 $string = preg_replace_callback("~({$format_one}|{$format_two_and_three}|{$format_four})~", 'stripFormatting', $string); echo $string; ?> PHP: Its better trying then assuming.
Ahh, my fault. Didn't even notice that you were using a different function. Just tested with that function and works like a charm. Here are my final results: function format_number($phone){ $phone = preg_replace("#[^\d{10}\s]#",'',$phone[1]); if(strlen($phone) == 10) { error_log("Is 10 digits"); $area = substr($phone,0,3); $prefix = substr($phone,3,3); $number = substr($phone,6,4); $format = "".$area.".".$prefix.".".$number; $phone = $format; } return("<say-as interpret-as=\"vxml:phone\">".$phone."</say-as>"); } $format1 = '\d{10}'; $format2 = '\d{3}(\.|\-)\d{3}\2\d{4}'; $format3 = '\(\d{3}\)\-\d{3}\-\d{4}'; $body = preg_replace_callback("~({$format1}|{$format2}|{$format3})~", 'format_number', $body); PHP: