Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format a Phone Number (Detect and add the country code if missing)

Tags:

regex

php

I have the following regex query that I built the idea is to take user input (phone numbers) and then make sure all the numbers are the exact same format when I store it in the database.

The problem I have is that this regex of mine does not cater for all the scenarios, I will explain in a bit.

This is my current code:

//format phone numbers
function Number_SA($number)
{
    //strip out everything but numbers
    $number =  preg_replace("/[^0-9]/", "", $number);
    //Strip out leading zeros:
    $number = ltrim($number, '0');
    //The default country code
    $default_country_code  = '+27';
    //Check if the number doesn't already start with the correct dialling code:
    if ( !preg_match('/^[+]'.$default_country_code.'/', $number)  ) {
        $number = $default_country_code.$number;
    }
    //return the converted number:
    return $number;
}

The behavior I want is the following; If a user enters any of the following formats the number should end up as +27

  • 797734809 #missing a leading 0
  • 0797734809
  • 27797734809
  • +27797734809

Should all be converted to:

  • +27797734809

PS: I first clean the number input with this:

function clean_input($data) 
{
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}

And then I use the Number_SA($number) function on the number. In other words:

$number = clean_input($_POST["cell_number"]);
$msisdn = Number_SA($number);

PPS: Number_SA, the SA stands for South Africa since I live there and I want this to work for our country code which is +27

Solution, I ended up with @Kamil Kiełczewski answer by building it into my program as follows:

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    if (empty($_POST["cell_numbers"])) {
        $err = "Please add numbers!";
    } else {
        $numbers = test_input($_POST["cell_numbers"]);
        $numbers = explode("\n", str_replace("\r", "", $numbers));
        foreach ($numbers as $number) {
            $msisdn = preg_replace('/^(?:\+27|27|0)?/','+27', $number);
            //insert into the database
        }        
    }
}
like image 727
Erik Thiart Avatar asked Oct 15 '25 15:10

Erik Thiart


1 Answers

Here is your regexp:

^(?:\+27|27|0)?(\d*)

and if it match something use this: +27$1

Here is working example (improved): https://regex101.com/r/VaUAKN/7

EXPLANATION:

First we wanna split prefix (if exists) with number: ^(?:\+27|27|0)? the ?: inside group makes that prefix group will be ignored in results. The ^ means begining of line. The last ? allow prefix to not exists. And at the end (\d*) catch numbers after prefix

PHP working example (Wiktor Stribiżew noted that in regexp we can can omit (\d*) and $1 and change \+27|27 to \+?27 ):

$numOld = "2712345678";
$num = preg_replace('/^(?:\+?27|0)?/','+27', $numOld); // > $num = "+2712345678"
like image 56
Kamil Kiełczewski Avatar answered Oct 18 '25 08:10

Kamil Kiełczewski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!