Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

International phone number validation

I need to do pretty basic phone-number validation and formatting on all US and international phone numbers in Python. Here's what I have so far:

import re 

def validate(number):
    number = re.compile(r'[^0-9]').sub('', number)
    if len(number) == 10:
        # ten-digit number, great
        return number
    elif len(number) == 7:
        # 7-digit number, should include area code
        raise ValidationError("INCLUDE YOUR AREA CODE OR ELSE.")
    else:
        # I have no clue what to do here

def format(number):
    if len(number) == 10:
        # basically return XXX-XXX-XXXX
        return re.compile(r'^(\d{3})(\d{3})(\d{4})$').sub('$1-$2-$3', number)
    else:
        # basically return +XXX-XXX-XXX-XXXX
        return re.compile(r'^(\d+)(\d{3})(\d{3})(\d{4})$').sub('+$1-$2-$3-$4', number)

My main problem is that I have NO idea as to how international phone numbers work. I assume that they're simply 10-digit numbers with a \d+ of the country code in front of them. Is this true?

like image 413
Naftuli Kay Avatar asked Dec 06 '11 21:12

Naftuli Kay


2 Answers

E.164 numbers can be up to fifteen digits, and you should have no expectation that beyond the country code of 1-3 digits that they will fit any particular form. Certainly there are lots of countries where it is not XXX-XXX-XXXX. As I see it you have three options:

  1. Painstakingly create a database of the number formats for every country code. Then check each country individually for updates on a periodic basis. (Edit: it looks like Google already does this, so if you trust them and the Python porter to keep libphonenumber correct and up to date, and don't mind upgrading this library every time there is a change, that might work for you.)
  2. Eliminate all delimiters in the supplied telephone numbers and format them without any spacing: +12128675309
  3. Format the numbers as the user supplies them rather than reformatting them yourself incorrectly.
like image 116
Michael Hoffman Avatar answered Oct 22 '22 05:10

Michael Hoffman


I ignore the format as in where are the spaces and dashes. But here is the regex function I use to validate that numbers:

  • eventually, start with a + and some digits for the country code
  • eventually, contain one set of brackets with digits inside for area code or optional 0
  • finish with a digit
  • contain spaces or dashes in the number itself (not in the country or area codes):
def is_valid_phone(phone):
    return re.match(r'(\+[0-9]+\s*)?(\([0-9]+\))?[\s0-9\-]+[0-9]+', phone)
like image 25
Erwan Avatar answered Oct 22 '22 05:10

Erwan