Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

grupos no regex

Olá instrutores, tudo bem? Estou com uma dúvida com relação aos grupos no regex. No formulário do testador de regex, coloquei como alvo: Eu adoro tomar suco de laranja. E a minha regex ficou assim: (\w+\s+)+. Antes de executar a regex, marquei a opção mostra grupos no formulário e mandei executar. Quando eu fiz isso, o sistema encontrou no match inteiro: Eu adoro tomar suco de , uma vez que neste grupo deve conter um ou mais caracteres seguidos de um ou mais espaços. No entanto, após as |||, que mostram os grupos, ele só exibiu como grupo de . Por que será que nos grupos ele pega a última ocorrência do match, enquanto que no match inteiro ele exibe tudo? Gostaria de entender melhor o funcionamento da regex neste ponto. Agradeço pela oportunidade, e aguardo retorno. Abraços.

8 respostas

Tem a ver com a regex ser gananciosa, conforme a Aula 5.

Acho melhor também usar o console do navegador (com F12), ao invés da página de testes.

A regex (\w+\s+)+ vai tentar pegar o máximo de texto possível.

var regex = /(\w+\s+)+/g; // undefined
var texto = "Eu adoro tomar suco de laranja."; // undefined
regex.exec(texto); // (2) ["Eu adoro tomar suco de ", "de ", index: 0, input: "Eu adoro tomar suco de laranja."]
regex.exec(texto); // null

Colocando a ? no final, de maneira que a regex fique preguiçosa, ela vai "desistir" logo:

var regex = /(\w+\s+)+?/g; // undefined
var texto = "Eu adoro tomar suco de laranja."; // undefined
regex.exec(texto); // (2) ["Eu ", "Eu ", index: 0, input: "Eu adoro tomar suco de laranja."]
regex.exec(texto); // (2) ["adoro ", "adoro ", index: 3, input: "Eu adoro tomar suco de laranja."]
regex.exec(texto); // (2) ["tomar ", "tomar ", index: 9, input: "Eu adoro tomar suco de laranja."]
regex.exec(texto); // (2) ["suco ", "suco ", index: 15, input: "Eu adoro tomar suco de laranja."]
regex.exec(texto); // (2) ["de ", "de ", index: 20, input: "Eu adoro tomar suco de laranja."]
regex.exec(texto); // null

Olá instrutores, tudo bem? Agradeço pela resposta da minha dúvida. Fiz os testes conforme recomendado e realmente deu certo. Mas a dúvida ainda persiste. Por que que em uma expressão gananciosa o console do navegador, ou qualquer outra ferramenta não consegue selecionar todos os integrantes de um grupo, enquanto em uma preguiçosa isso acontece? Pelo o que tenho observado, é como se o valor da variável de resultados referente aos grupos, no caso resultado[1] fosse sobrescrito a cada iteração. Isso acontece mesmo? Isso explicaria o porquê em uma expressão gananciosa o programa só pega a última parte do grupo e não todo o grupo? Agradeço desde já.

Oi, Guido!

Acho que entendi a sua questão!

Repetir a captura é diferente de capturar a repetição.

Quando você faz /(\w+\s+)+/, você tá apenas repetindo a captura. O que a regex vai fazer é capturar o último elemento.

Acho que o ideal seria fazer /((\w+\s+)+)/ em que você também captura a repetição.

Veja:

var regex = /((\w+\s+)+)/g; // undefined

var texto = "Eu adoro tomar suco de laranja."; // undefined

regex.exec(texto); // (3) ["Eu adoro tomar suco de ", "Eu adoro tomar suco de ", "de ", index: 0, input: "Eu adoro tomar suco de laranja."]

regex.exec(texto); // null

Uma referência sobre o assunto: https://www.regular-expressions.info/captureall.html

Um bom site para testar suas regex é: https://regex101.com/r/hKNBgu/1

Ah, mais uma dica!

Você pode usar o ?: em um grupo, para que ele agrupe os resultados mas não capture os trechos. É o non capturing group.

Aí, sua regex poderia ser assim: ((?:\w+\s+)+)

Olá Instrutores, tudo bem? Testei a solução recomendada por vocês, e realmente agora ele está fazendo a captura da repetição como o desejado. Só gostaria de saber se existe uma explicação para o porquê que antes a regex só estava capturando todo o match e só o último elemento do grupo? Ou seja, o que fez a regex capturar apenas o último elemento do grupo no exemplo anterior? Agradeço desde já.

solução!

Olá, Guido!

Você fazer (REGEX)+, ou seja, capturar um grupo com ( e ) e depois fazer a repetição com +, tem esse efeito: - o group terá só o último elemento capturado. - o match será o resultado todo

Já você fazer (REGEX+), ou seja, fazer uma repetição com + e depois capturar isso num grupo com ( e ), tem outro efeito: - tanto o group como match serão o todo

Agradeço aos instrutores que me atenderam, no intuito de me auxiliarem no esclarecimento da minha dúvida.