How to make a regular expression for cell phone?

16

How to create a regular expression to validate the phone field that accepts 99-99999999 (DDD + 8 numbers) or 99-999999999 (DDD + 9 numbers). And when typing it add the - dash automatically!

ValidationExpression="^[0-9]{2}-([0-9]{8}|[0-9]{9})"

How to proceed?

    
asked by anonymous 13.01.2015 / 13:23

5 answers

39

NOTE: This response was originally written in 2015 and has been somewhat outdated. The original text was retained, but see the update at the end.

How about using ^[1-9]{2}\-[2-9][0-9]{7,8}$ ?

Explanation:

  • ^ - String start.
  • [1-9]{2} - Two digits 1 through 9. There are no DDD codes with the digit 0.
  • \- - A hyphen.
  • [2-9] - The first digit. It will never be 0 or 1.
  • [0-9]{7,8} - The remaining 7 or 8 digits, totaling 8 or 9 digits.
  • $ - End of string.

I would personally prefer to format the phone as (xx) xxxxx-xxxx . And for that, I would use this regular expression: ^\([1-9]{2}\) [2-9][0-9]{3,4}\-[0-9]{4}$ . Explanation:

  • ^ - String start.
  • \( - One opens parentheses.
  • [1-9]{2} - Two digits 1 through 9. There are no DDD codes with the digit 0.
  • \) - Closes parentheses.
  • - A blank space.
  • [2-9] - The first digit. It will never be 0 or 1.
  • [0-9]{3,4} - The remaining digits of the first half of the phone number, making a total of 4 or 5 digits in the first half.
  • \- - A hyphen.
  • [0-9]{4} - The second half of the phone number.
  • $ - End of string.

There are some special cases still. For example, a phone number will never start with 90, which is the prefix to make collect calls. With this the regular expression looks like this:

^\([1-9]{2}\) (?:[2-8][0-9]|9[1-9])[0-9]{2,3}\-[0-9]{4}$

In this block (?:[2-8][0-9]|9[1-9]) represents a choice between [2-8][0-9] and 9[1-9] :

  • The [2-8][0-9] means that if the first digit is from 2 to 8, the second is from 0 to 9.
  • The 9[1-9] means that if the first digit was 9, the second should be 1 to 9 (it can not be 0).
  • Again, the first digit will never be 0 or 1.

[Edited] The above part of this answer was written in 2015. At the time, there were 8 or 9-digit cell phones, depending on the DDD. Nowadays all cell phones in Brazil have nine digits and start with digit 9 and all fixed phones have 8 digits and never start with digit 9. So the best regular expression for this would be this:

^\([1-9]{2}\) (?:[2-8]|9[1-9])[0-9]{3}\-[0-9]{4}$

The full explanation of it is:

  • ^ - String start.
  • \( - One opens parentheses.
  • [1-9]{2} - Two digits 1 through 9. There are no DDD codes with the digit 0.
  • \) - Closes parentheses.
  • - A blank space.
  • (?:[2-8]|9[1-9]) - The beginning of the number. Represents a choice between [2-8] and 9[1-9] . | separates the options to be chosen. (?: ... ) groups such choices. Fixed phones start with digits 2 to 8. Cell phones start with 9 and have a second digit from 1 to 9. The first digit will never be 0 or 1. Cell phones can not start with 90 because that is the prefix for calls to charge.
  • [0-9]{3} - The remaining three digits of the first half of the phone number, making a total of 4 or 5 digits in the first half.
  • \- - A hyphen.
  • [0-9]{4} - The second half of the phone number.
  • $ - End of string.
13.01.2015 / 13:36
5

My solution may not be the most effective, but as I have not seen many solutions commenting on some points I decided to write mine.

I created a regular expression that identifies whether a string is a phone, taking into account the following cases:

  
  • 0800 Phones
  •   
  • Carrier and service numbers like 10315 and 190
  •   
  • Telephones represented with or without parentheses
  •   
  • Accepts operator represented as 0xx11
  •   
  • Phones with or without tabs [.-]
  •   
  • Ignore phones starting with 0 if you do not have DDD (ex: 0999-9999 is not accepted, but 0xx11 is 9123-1234)
  •   

It got a little big and hard to read humanly, but it suits my projects:

/^1\d\d(\d\d)?$|^0800 ?\d{3} ?\d{4}$|^(\(0?([1-9a-zA-Z][0-9a-zA-Z])?[1-9]\d\) ?|0?([1-9a-zA-Z][0-9a-zA-Z])?[1-9]\d[ .-]?)?(9|9[ .-])?[2-9]\d{3}[ .-]?\d{4}$/gm

You can see the expression

After validating if the expression is a phone, you can format it any way you think best by manipulating the string.

Here is an example in Java (where PHONE_MATCH is the regular expression):

public String phone(String phoneString) throws IllegalArgumentException {
    if (!phoneString.matches(PHONE_MATCH)) {
        throw new IllegalArgumentException("Not a valid phone format");
    }

    String str = phoneString.replaceAll("[^\d]", "");

    if (str.charAt(0) == '0') {
        if (str.charAt(1) == '0') {
            str = str.substring(2);
        } else {
            str = str.substring(1);
        }
    }

    switch (str.length()) {
        case 8:
            return applyMask(str, "AAAA-AAAA", 'A');
        case 9:
            return applyMask(str, "AAAAA-AAAA", 'A');
        case 10:
            return applyMask(str, "(AA) AAAA-AAAA", 'A');
        case 11:
            return applyMask(str, "(AA) AAAAA-AAAA", 'A');
        default:
            return str;
    }
}

ApplyMask method:

public String applyMask(String str, String mask, char specialChar) {

    // Conta quantos caracteres especiais existem na máscara
    int maskChCount = mask.length() - mask.replaceAll("[^" + specialChar + "]", "").length();

    // Conta apenas os números
    int strChCount = str.length() - str.replaceAll("\d", "").length();

    // Exceção caso a string nao tenha números suficientes para competar a máscara
    if (strChCount < maskChCount) {
        throw new IllegalArgumentException("The number of chars in the string should not be smaller than the " +
                "number of special chars in the mask");
    }

    char[] maskChars = mask.toCharArray();
    char[] strChars = str.toCharArray();

    // Itera por todos os elementos da máscara
    for (int i = 0, j = 0; i < maskChars.length && j < strChars.length; i++) {
        char ch = maskChars[i];
        char sh = strChars[j];

        if (ch == specialChar) {
            // Se achou o caractere especial, buscar o próximo elemento aceito da String e 
            // substituí-lo no local do caractere especial
            while (!Character.toString(sh).matches("\d")) {
                j++;
                sh = strChars[j];
            }
            maskChars[i] = sh;
            j++;
        }
    }

    return new String(maskChars);
}

I think you have several ways to optimize this code, any suggestions are welcome.

    
16.06.2016 / 20:59
2

I use this

@"^\(?\d{2}\)?[\s-]?[\s9]?\d{4}-?\d{4}$"

If you enter 9 digits she thanks you for the first digit to be 9.

I would take a little bit of each example to set up the ideal.

    
26.08.2015 / 22:36
2

People, with the help of you, I created a string that I found to be ideal for me. Simple and straightforward. In WHMCS use to start and close /. I will not use the example to follow your example. Come on. The expression looks like this:

^\([1-9]{2}\) [9]{0,1}[6-9]{1}[0-9]{3}\-[0-9]{4}$

Explanation:

  • ^ = String start.
  • \( = One opens parentheses.
  • [1-9]{2} = Two digits 1 to 9. There are no DDD codes with the digit 0.
  • \) = One closes parentheses.
  • = A blank space.
  • [9]{0,1} = The first digit is 9, plus it may or may not exist from there "0" or "1" within {0,1}.
  • [6-9]{1} = the second digit can be 6 to 9.
  • [0-9]{3} = The three other digits are 0 through 9
  • \- = A hyphen.
  • [0-9]{4} = The second half of the phone number.
  • $ = End of string.

Remembering friends in WHMCS should start and close with /. By the end of 2016 or more precise on November 6, 2016 all Brazil will have the 9 in the beginning of the cell phones.

    
09.12.2015 / 19:41
0

^ ([1-9] {2}) 9 [7-9] {1} [0-9] {3} - [0-9] {4} p>

[1-9] {2} = Two digits from 1 to 9. There are no DDDs with the digit 0.
9 = All mobile phones from 2016 start with 9
[7-9] {1} = In old numbering, cell phones started with 7.8 or 9
[0-9] {3} = The three other digits can be from 0 to 9
[0-9] {4} = The four after the hyphen can be 0 to 9

    
08.09.2017 / 20:31