replace using regular expressions

Asked

Viewed 1,288 times

4

I am running a replace with regular expressions to format a string, such as CPF:

var cpf = '99999999999';
cpfFormatado = cpf.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$+');
console.log(cpfFormatado); // 999.999.999-99

I am trying to reduce the regular expression, however I am not able to find the correct way to use the groups in the substitution string:

var cpf = '99999999999';
cpfFormatado = cpf.replace(/(\d{3}){3}(\d{2})/, '$1.$2.$3-$+');
console.log(cpfFormatado); // 999.99.$3-99

How could I get the same result from the first code using the regular expression of the second?

  • 2

    that’s what you’re looking for? (\d{3})(\1)(\1)(\d{2})

  • Your first exit is wrong, the last group is $4.

  • @Luishenrique is not wrong. $+ picks up the last found group, ie will return the group (\d{2}). Utilise $4 would give the same result.

  • @Guilhermelautert His expression worked perfectly. He could write a reply explaining how it works?

  • Strange that I circled here on the console and it didn’t work.

2 answers

4


Can’t do that. When you reduce (\d{3})(\d{3})(\d{3}) for that reason (\d{3}){3}, you are eliminating two capture groups, the first capture group will be overwritten twice, causing it to take the value of the last catch.

var cpf = '12345678901';
cpfFormatado = cpf.replace(/(\d{3}){3}(\d{2})/, '$1.$2.$3-$+');
console.log(cpfFormatado); // 789.01.$3-$+

To know what is available to use, just use a Replacement function, and see what it takes as arguments:

var cpf = '12345678901';
cpfFormatado = cpf.replace(/(\d{3}){3}(\d{2})/, function() {
    debugger; // ao parar aqui vamos ver o que tem dentro de arguments
    console.log(JSON.stringify(arguments));
});

The arguments passed to the function in the above example are:

["12345678901", "789", "01", 0, "12345678901"]

See how "789" appears in group 1.

  • Good observation, I had not noticed that the group was being overwritten.

  • Although parse semantics are the same, when you need to use group values, it is sometimes necessary to decompose the regex.

0

As requested:

(\d{3})(\1)(\1)(\d{2})

Composition

(\d{3})   -  grupo nº 1
(\1)      -  grupo nº 2, que utiliza a mesma expressão do grupo 1
(\1)      -  grupo nº 3, que utiliza a mesma expressão do grupo 1
(\d{2})   -  grupo nº 4

Explanation

You can make use of already made expressions, making them a group and calling by shortcuts \1-\9, remembering that one can only have a maximum of 9 shortcuts \9.

In short (\d{3}) is the grouped expression that has shortcut \1

  • This will not capture the CPF "12345678901"

  • 1

    \1 until \9 is used to refer to a previous catch, not a previous expression.

  • 1

    \1 is not a shortcut to the same expression as the capture group 1, it is a backreference pro that was captured in group 1. Your regex will only accept Cpfs whose 3 groups of 3 digits are equal.

  • In fact, I’m sorry for the mistake.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.