How to make a regular expression for mobile phone?
How to create a regular expression to validate the phone field you accept 99-99999999 (DDD + 8 numbers) or 99-999999999 (DDD + 9 numbers). And that when typing it adds The Dash - automatically!
ValidationExpression="^[0-9]{2}-([0-9]{8}|[0-9]{9})"
How to proceed?
5 answers
Nowadays all mobile phones in Brazil have nine digits and start with the digit 9 and all landline phones have 8 digits and never start with the digit 9. I personally would prefer to format the phone as (xx) xxxxx-xxxx
. Therefore, 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:
-
^
- start of string. -
\(
- One opens parentheses. -
[1-9]{2}
- two digits from 1 to 9. There are no codes of DDD with the digit 0. -
\)
- one closes parentheses. -
-
(?:[2-8]|9[1-9])
- the beginning of the number. Represents a choice between a digit between 2 and 8 (the part of[2-8]
) and a 9 followed by a digit from 1 to 9 (the part of9[1-9]
). The|
separates the options to be chosen.(?: ... )
groups such choices. Landline phones start with digits from 2 to 8. Mobile phones start with 9 and have a second digit from 1 to 9. The first digit never it will be 0 or 1. Cell phones can't start with 90 because that's 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.
If you want to leave parentheses, whitespace and hyphen optional, then you can put a ?
after each of these symbols, resulting in this regular expression:
^\(?[1-9]{2}\)? ?(?:[2-8]|9[1-9])[0-9]{3}\-?[0-9]{4}$
If you want, you can also filter the DDDs that exist. Here is an image that shows the currently existing area codes according to the Wikipedia :
Then looking at this map, the subexpression that would filter out valid DDDs would be as follows:
(?:[14689][1-9]|2[12478]|3[1234578]|5[1345]|7[134579])
As already explained, the (?: ... )
is for grouping. The options (separate by |
) would be two-digit groups, which would be one of the following options: 2[12478]
for Rio de Janeiro and Espírito Santo, 3[1234578]
for Minas Gerais, 5[1345]
for Rio Grande do Sul, 7[134579]
for Bahia and Sergipe and [14689][1-9]
for the rest of Brazil.
And the full regular expression would be as follows (with the required parentheses, spaces, and hyphens):
^\((?:[14689][1-9]|2[12478]|3[1234578]|5[1345]|7[134579])\) (?:[2-8]|9[1-9])[0-9]{3}\-[0-9]{4}$
And with them not mandatory:
^\(?(?:[14689][1-9]|2[12478]|3[1234578]|5[1345]|7[134579])\)? ?(?:[2-8]|9[1-9])[0-9]{3}\-?[0-9]{4}$
Note: This answer was originally written in 2015, when there were 8-or 9-digit cell phones, depending on the DDD. Since then, it has been updated to the newest format in force, which always have 9 digits. For more details on how this response was edited, check out the edit history.
My solution may not be the most effective, but since I did not see 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 such as 10315 and 190
- phones represented with or without parentheses
- accepts operator represented as 0xx11
- phones with or without the [tabs .-]
- ignores phones starting with 0 if it does not have DDD (ex: 0999-9999 is not accepted, but 0xx11 9123-1234 is)
Got a little big and hard to read humanly, but it caters to 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 in use in this link .
After you validate if the expression is a phone, you can format it the way you see fit by manipulating the string.
Follows 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 believe you have several ways to optimize this code, any suggestion is welcome.
I use this
@"^\(?\d{2}\)?[\s-]?[\s9]?\d{4}-?\d{4}$"
If you put 9 digits she thanks you that the first digit is 9.
I would take a little of each example to assemble the ideal.
Folks, with your help I created a string that I thought was right 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:
-
^
= start of string. -
\(
= One opens parentheses. -
[1-9]{2}
= two digits from 1 to 9. There are no DDD codes with the digit 0. -
\)
= one closes parentheses. -
= Um espaço em branco.
-
[9]{0,1}
= O first digit is 9, plus it may or may not exist hence the " 0 " or "1" within the {0,1}. -
[6-9]{1}
= the second digit can be from 6 to 9. -
[0-9]{3}
= the other three digits are from 0 to 9 -
\-
= a hyphen. -
[0-9]{4}
= the second half of the phone number. -
$
= end of string.
Reminding friends that in WHMCS one should start and close with/. By the end of 2016 or more accurate on November 06, 2016 all of Brazil will have the 9 in start of mobile phones.
^\([1-9]{2}\) 9[7-9]{1}[0-9]{3}\-[0-9]{4}$
-
[1-9]{2}
= two digits from 1 to 9. There are no DDD with the digit 0. -
9
= all mobiles as of 2016 start with 9 -
[7-9]{1}
= in the old numbering the phones started with 7, 8 or 9 -
[0-9]{3}
= the other three digits can be from 0 to 9 -
[0-9]{4}
= the four after the hyphen can be from 0 to 9