Regular expression to validate a field that accepts CPF or CNPJ

I have a <input> in the form that should accept CPF or CNPJ.

I will use in the back-end in PHP the value to save either in the field " cpf" or in the field " cnpj" of a table in the database.

I'm using AngularJS and I need a regular expression to put in ng-pattern, to accept only usable data.

I am not interested in validating the check digits at this time end.

I want to be a bit flexible, allowing the user to use points, Dash and slash if they want, or just numbers.

 45
Author: J. Bruni, 2014-03-30

4 answers

Solution:

This solution validates these formats: 00000000000, 00000000000000, 000.000.000-00, 00.000.000/0000-00 and up to 000000000-00 or 00000000/0000-00, for example. Dots and dashes are optional in each of the positions.

What is not accepted, for example: 000-000-000-00 (but can be changed as noted below)

Regex:

([0-9]{2}[\.]?[0-9]{3}[\.]?[0-9]{3}[\/]?[0-9]{4}[-]?[0-9]{2})|([0-9]{3}[\.]?[0-9]{3}[\.]?[0-9]{3}[-]?[0-9]{2})

Click here and take your tests in realtime on regexpal.

Explanation:

  • [0-9]{2} character range: 0 to 9, quantity: 2 characters;
  • [0-9]{3} character range: 0 to 9, Quantity: 3 characters;
  • [0-9]{4} Character range: 0 to 9, quantity: 4 characters;
  • [\.]? a point, optional. It was used \ in the DOT, because it alone is special character;
  • [-]? a dash, optional (if you add other characters, start with-always);
  • [\/]? a bar, optional. Also "escape" with \ to please the PCRE ;
  • (grupo1)|(grupo2) if one of the groups validates, the expression is valid.

If you want to accept other separators, just add between [ ].
Example: [-\.\/]? will accept both - and . and / in that position (? = or nothing).

To adapt to other" dialects " of regexp , some possible variations would be to take the escape from the bar (\/ => /) and optionally put a ^ at the beginning and a $ at the end of the line.

 89
Author: Bacco, 2014-03-30 10:27:13

Regular expression to validate a field that accepts CPF or CNPJ (no calculation of the checking digits):

/^([0-9]{3}\.?[0-9]{3}\.?[0-9]{3}\-?[0-9]{2}|[0-9]{2}\.?[0-9]{3}\.?[0-9]{3}\/?[0-9]{4}\-?[0-9]{2})$/

It can be understood like this (where " cpf "is the expression to validate CPF and "cnpj" is the expression to validate CNPJ):

/^(cpf|cnpj)$/

The start and end bars (/) are not part of the expression itself - they are just delimiters. The character ^ at the beginning and the character $ at the end require the full content of the string to be validated to match to the expression between them. The parentheses containing the vertical bar (a|b) create an alternative "option" between "a" and "b". Satisfying either of the two expressions, the result will be positive. Instead of "a " and " b", we then have the specific expressions for CPF and CNPJ, separately.

For CPF:

[0-9]{3}\.?[0-9]{3}\.?[0-9]{3}\-?[0-9]{2}

The query (?) makes the preceding character specification optional . Therefore the points and the trace are optional. The character class [0-9] represents any character from 0 to 9 (we could use \d, but I prefer [0-9] because it's more readable). Finally, the number in square brackets ({3}) determines a specific amount of times that the preceding character specification should repeat. Therefore, a total of 11 numeric characters are required(3 + 3 + 3 + 2).

For CNPJ, the structure is similar:

[0-9]{2}\.?[0-9]{3}\.?[0-9]{3}\/?[0-9]{4}\-?[0-9]{2}

A total of 14 are required here numeric characters(2 + 3 + 3 + 4 + 2).

Remembering that the backslash (\) before the period (.) and other special characters is an "escape" character, which serves to disregard the special interpretation of the next character and consider it literally. (The dot, without "escape", means"any character". With "escape", it merely means the character" point " itself.)


To know if it is CPF or CNPJ

On the server side, in PHP, it is made the selection between CPF or CNPJ considering the number of digits present in the field:

$numeros = preg_replace('/[^0-9]/', '', $valor);

if (strlen($numeros) == 11)
{
    $cliente->cpf = $valor;
}
elseif (strlen($numbers) == 14)
{
    $cliente->cnpj = $valor;
}

Note: this does not replace the validation done by the regular expression we saw above, which is also performed on the server side (in my case the rules are embedded in the model, with the same validation regular expressions we saw above for CPF and CNPJ, only separate - each in its respective field).

 19
Author: J. Bruni, 2014-05-13 18:48:33

For a simple input (allows you to type only CPF or CNPJ):

^(\d{2}\.?\d{3}\.?\d{3}\/?\d{4}-?\d{2}|\d{3}\.?\d{3}\.?\d{3}-?\d{2})$

For an input or text box where the CPF or CNPJ can appear at the beginning, middle, or end of a text:

(?<=\D|^)(\d{2}\.?\d{3}\.?\d{3}\/?\d{4}-?\d{2}|\d{3}\.?\d{3}\.?\d{3}-?\d{2})(?=\D|$)

the main difference is the use of " look behind "and" look ahead " to ensure that the CPF or CNPJ digits are preceded/succeeded by non-numeric characters. Without this, there would be the match of a sequence of, for example, 20 digits!

 1
Author: Paulo Merson, 2018-10-22 17:02:46

E-mail: "^([-a-zA-Z0-9_-]*@(gmail|yahoo|ymail|rocketmail|bol|hotmail|live|msn|ig|globomail|oi|pop|inteligweb|r7|folha|zipmail).(com|info|gov|net|org|tv)(.[-a-z]{2})?)*$"

CPF: "^((\d{3}).(\d{3}).(\d{3})-(\d{2}))*$"

CNPJ: "^((\d{2}).(\d{3}).(\d{3})/(\d{4})-(\d{2}))*$"

CPF / CNPF: "^(((\d{3}).(\d{3}).(\d{3})-(\d{2}))?((\d{2}).(\d{3}).(\d{3})/(\d{4})-(\d{2}))?)*$"

Ex.: (VB.NET)

Dim hRegex As Regex = New Regex("^(((\d{3}).(\d{3}).(\d{3})-(\d{2}))?((\d{2}).(\d{3}).(\d{3})/(\d{4})-(\d{2}))?)*$", RegexOptions.None)

MsgBox(hRegex.IsMatch($"000.000.000-00")) 'Saída {True|False}
 -5
Author: Fábio Yehudi, 2018-02-20 10:04:01