37

I use Clickatell to send SMSes to clients' mobile phones.

Is there a standardised regular expression for all valid mobile phone numbers, e.g. +27 123 4567? I'd roll my own, but I'm worried about missing an obscure, valid phone number format.

Petrus Theron
  • 27,855
  • 36
  • 153
  • 287
  • 3
    Why not try sending an SMS to the number your customer gives you? Have the SMS contain a unique code that the customer needs to enter in order to proceed. – Tim Pietzcker Feb 21 '11 at 13:27
  • 2
    Whoa!! You said this back in 2011. And today we have this widely used concept of OTP. – sid-m Feb 26 '19 at 15:33

6 Answers6

52

After stripping all characters except '+' and digits from your input, this should do it:

^\+[1-9]{1}[0-9]{3,14}$

If you want to be more exact with the country codes see this question on List of phone number country codes

However, I would try to be not too strict with my validation. Users get very frustrated if they are told their valid numbers are not acceptable.

Community
  • 1
  • 1
Jannie Theunissen
  • 28,256
  • 21
  • 100
  • 127
  • I think even that's too strict; the size of the international prefix and local number can both vary. – dwarring May 16 '11 at 05:40
  • @snoopy: last time I checked it looked like the digits in [international prefix] + [local number] is constant - i.e. smaller countries with shorter local numbers have a longer country prefix. – Jannie Theunissen May 18 '11 at 14:41
  • I took my information from http://www.workingsoftware.com.au/page/International_Mobile_Number_Validation_PT_II which maintains a list of international mobile number formats. Have copied the list to http://pastebin.com/ziYj1uy4 – dwarring May 18 '11 at 21:17
  • 1
    @snoopy: good link! Yes, in that case ^\+[1-9]{1}[0-9]{7,11}$ is probably the strictest one can go. – Jannie Theunissen May 23 '11 at 11:30
  • It didn't validate 12 digit UK number (for ex +447735234817) – Manish Jain Sep 12 '14 at 22:02
  • Check your syntax @Manish and try again: http://refiddle.com/refiddles/5415ed5875622d4df7370a00 – Jannie Theunissen Sep 14 '14 at 19:35
  • 9
    According to [E.164](https://en.wikipedia.org/wiki/E.164) international number can be 15 digits long and has no minimum length, other than the country code - at least one digit, and the subscriber number - at least one digit (shortest I've seen is three digits). So the above regex should be: `^\+[1-9]{1}[0-9]{1,14}$` – Sergei Feb 11 '15 at 08:37
  • 1
    Excellent reference, Sergei! I'll adapt my answer, but will consider suspicious anyone with an international telephone number shorter than four digits. – Jannie Theunissen Feb 11 '15 at 13:26
  • 1
    Fair enough. The shortest one I've found so far was from NZ and was 5 digits long: +64010. Since E.164 doesn't define minimum, personally, I would allow for a two digit-long international number just to be future proof. – Sergei Feb 13 '15 at 12:47
  • 4
    Regardless of any specific country code, this `^([0|\+[0-9]{1,5})?([0-9]{10})$` will also work for generic phone numbers, starting from either `+` or any other number – sohaiby Jun 04 '15 at 13:49
  • this not works on whole countries. because prefix length and whole digits length variable. so may regex not complete solution. – Mahdi Nov 22 '15 at 07:06
  • This does not validate phone numbers with '00' prefix. "+420"=="00420" – zdarsky.peter Jan 31 '16 at 23:18
  • @zdarsky.peter unless your app will be for users from only one country, it is best practice to reject numbers that start with any county's international dialling prefix instead of a `+`. From the example given in the question, it is clear that the OP thinks so too. – Jannie Theunissen Feb 01 '16 at 07:52
  • I used @"^[1-9+]{1}[0-9]{3,14}" in C# – Per G Mar 04 '19 at 07:59
6

Even if you write a regular expression that matches exactly the subset "valid phone numbers" out of strings, there is no way to guarantee (by way of a regular expression) that they are valid mobile phone numbers. In several countries, mobile phone numbers are indistinguishable from landline phone numbers without at least a number plan lookup, and in some cases, even that won't help. For example, in Sweden, lots of people have "ported" their regular, landline-like phone number to their mobile phone. It's still the same number as they had before, but now it goes to a mobile phone instead of a landline.

Since valid phone numbers consist only of digits, I doubt that rolling your own would risk missing some obscure case of phone number at least. If you want to have better certainty, write a generator that takes a list of all valid country codes, and requires one of them at the beginning of the phone number to be matched by the generated regular expression.

user
  • 6,897
  • 8
  • 43
  • 79
  • I understand that not all mobile numbers exist, I just need to validate the format due to data entry errors (e.g. filling in the wrong field). – Petrus Theron Feb 21 '11 at 13:26
  • 1
    @FreshCode, that's not what I meant. What I am saying is that you can have phone numbers where there is absolutely no way to tell from the sequence of digits whether it's a landline or mobile phone. Since your question was for a regex to check whether a given string is a valid *mobile phone* number, this is relevant. – user Feb 21 '11 at 13:29
  • good point. I should probably clarify that by validity I mean, "a potential phone number", e.g. 12345, but not xyz123. – Petrus Theron May 29 '12 at 17:23
3
^\+[1-9]{1}[0-9]{7,11}$ 

The Regular Expression ^\+[1-9]{1}[0-9]{7,11}$ fails for "+290 8000" and similar valid numbers that are shorter than 8 digits.

The longest numbers could be something like 3 digit country code, 3 digit area code, 8 digit subscriber number, making 14 digits.

robert
  • 33,242
  • 8
  • 53
  • 74
2

Posting a note here for users looking into this into the future. Google's libphonenumber is what you most likely would want to use. There is wrappers for PHP, node.js, Java, etc. to use the data which Google has been collecting and reduces the requirements for maintaining large arrays of regex patterns to apply.

Eduard Luca
  • 6,514
  • 16
  • 85
  • 137
1

Even though it is about international numbers I would want the code to be like :

/^(\+|\d)[0-9]{7,16}$/;

As you can have international numbers starting with '00' as well.

Why I prefer 15 digits : http://en.wikipedia.org/wiki/E.164

Nasaralla
  • 1,839
  • 13
  • 11
0

// Regex - Check Singapore valid mobile numbers

public static boolean isSingaporeMobileNo(String str) {
    Pattern mobNO = Pattern.compile("^(((0|((\\+)?65([- ])?))|((\\((\\+)?65\\)([- ])?)))?[8-9]\\d{7})?$");
    Matcher matcher = mobNO.matcher(str);
    if (matcher.find()) {
        return true;
    } else {
        return false;
    }
}
John
  • 41
  • 1