Regular expression to validate a field that accepts CPF or CNPJ


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

In the back-end in PHP the value to save either in the " cpf " field or in the " cnpj " field 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'm not interested at this point in validating the check digits at the end.

I want to be a bit flexible, allowing the user to use dots, dash and bar if you want, or just numbers.

asked by anonymous 30.03.2014 / 06:56

4 answers



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 per note below)





  • [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;
  • [\.]? One point, optional. It was used \ at the point, as it is itself a special character;
  • [-]? A dash, optional (if you add other characters, start with - always);
  • [\/]? A slash, optional. Also "escaped" with \ to please PCRE ;
  • (grupo1)|(grupo2) If one of the groups validates, the expression is valid.

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

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

30.03.2014 / 07:00

Regular expression to validate a field that accepts CPF or CNPJ (without calculating the digits checkers):


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


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

For CPF:


The interrogation ( ? ) causes the preceding character specification to be optional . Therefore the points and the tracino are optional. The character type [0-9] represents any character from 0 to 9 (we could use \d , but I prefer [0-9] because it is more readable). Finally, the number in brackets (% w / o%) determines a specific number of times that the preceding character specification must be repeated. Thus, a total of 11 numeric characters (3 + 3 + 3 + 2) are required.

For CNPJ, the structure is similar:


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

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

To find out if you are a CPF or CNPJ

On the server side, in PHP, the selection is made 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 made by the regular expression we saw above, which is also performed on the server side (in my case the rules are embedded in the template with the same regular expressions of validation that we have seen above for CPF and CNPJ, only separate - each in its respective field).

13.05.2014 / 20:48

For a simple input (enter only CPF or CNPJ):


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


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

22.10.2018 / 19:02

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}
20.02.2018 / 06:46