Find 10-digit numbers in string

Discussion in 'PHP' started by Thorlax402, Aug 23, 2010.

  1. #1
    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
     
    Thorlax402, Aug 23, 2010 IP
  2. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #2
    <?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:
     
    Last edited: Aug 23, 2010
    danx10, Aug 23, 2010 IP
  3. nabil_kadimi

    nabil_kadimi Well-Known Member

    Messages:
    1,065
    Likes Received:
    69
    Best Answers:
    0
    Trophy Points:
    195
    #3
    Maybe this is what you want:
    $phone_number_raw = '123.456.7890';
    $phone_number = preg_replace('\D', '', $phone_number_raw);
    PHP:
     
    nabil_kadimi, Aug 23, 2010 IP
  4. Thorlax402

    Thorlax402 Member

    Messages:
    194
    Likes Received:
    2
    Best Answers:
    5
    Trophy Points:
    40
    #4
    Thank you both. Works as expected.
     
    Thorlax402, Aug 23, 2010 IP
  5. MyVodaFone

    MyVodaFone Well-Known Member

    Messages:
    1,048
    Likes Received:
    42
    Best Answers:
    10
    Trophy Points:
    195
    #5
    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.
     
    Last edited: Aug 24, 2010
    MyVodaFone, Aug 24, 2010 IP
  6. Thorlax402

    Thorlax402 Member

    Messages:
    194
    Likes Received:
    2
    Best Answers:
    5
    Trophy Points:
    40
    #6
    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.
     
    Thorlax402, Aug 24, 2010 IP
  7. MyVodaFone

    MyVodaFone Well-Known Member

    Messages:
    1,048
    Likes Received:
    42
    Best Answers:
    10
    Trophy Points:
    195
    #7
    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 ?
     
    MyVodaFone, Aug 24, 2010 IP
  8. Thorlax402

    Thorlax402 Member

    Messages:
    194
    Likes Received:
    2
    Best Answers:
    5
    Trophy Points:
    40
    #8
    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.
     
    Thorlax402, Aug 24, 2010 IP
  9. MyVodaFone

    MyVodaFone Well-Known Member

    Messages:
    1,048
    Likes Received:
    42
    Best Answers:
    10
    Trophy Points:
    195
    #9
    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):
     
    Last edited: Aug 24, 2010
    MyVodaFone, Aug 24, 2010 IP
  10. Thorlax402

    Thorlax402 Member

    Messages:
    194
    Likes Received:
    2
    Best Answers:
    5
    Trophy Points:
    40
    #10
    I need the numbers in the format of "800.555.1234". Seems to be the only one the interpreter works properly with.
     
    Thorlax402, Aug 24, 2010 IP
  11. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #11
    Sorry, what do you mean - do you want to convert the $1 (first match) to that format?
     
    danx10, Aug 24, 2010 IP
  12. MyVodaFone

    MyVodaFone Well-Known Member

    Messages:
    1,048
    Likes Received:
    42
    Best Answers:
    10
    Trophy Points:
    195
    #12
    Sorry I messed up editing this post, see post 9 for solution
     
    MyVodaFone, Aug 24, 2010 IP
  13. Thorlax402

    Thorlax402 Member

    Messages:
    194
    Likes Received:
    2
    Best Answers:
    5
    Trophy Points:
    40
    #13
    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.
     
    Thorlax402, Aug 24, 2010 IP
  14. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #14
    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, Aug 24, 2010 IP
  15. MyVodaFone

    MyVodaFone Well-Known Member

    Messages:
    1,048
    Likes Received:
    42
    Best Answers:
    10
    Trophy Points:
    195
    #15
    I don't know mate, its working fine in a file on its own.
     
    MyVodaFone, Aug 24, 2010 IP
  16. Thorlax402

    Thorlax402 Member

    Messages:
    194
    Likes Received:
    2
    Best Answers:
    5
    Trophy Points:
    40
    #16
    @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...
     
    Thorlax402, Aug 24, 2010 IP
  17. danx10

    danx10 Peon

    Messages:
    1,179
    Likes Received:
    44
    Best Answers:
    2
    Trophy Points:
    0
    #17
    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.
     
    danx10, Aug 24, 2010 IP
  18. Thorlax402

    Thorlax402 Member

    Messages:
    194
    Likes Received:
    2
    Best Answers:
    5
    Trophy Points:
    40
    #18
    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:
     
    Last edited: Aug 24, 2010
    Thorlax402, Aug 24, 2010 IP