Limitación de la avaricia en expresiones regulares en JavaScript
Las expresiones regulares son avariciosas por defecto. Esto significa que capturan la máxima cantidad posible de caracteres. Analicemos con un ejemplo. Supongamos que tenemos la siguiente cadena:
let str = 'aeeex zzz x kkk';
Supongamos que en esta cadena queremos encontrar la subcadena
'aeeex' usando el siguiente patrón: letra
'a', luego cualquier carácter uno o más
veces, luego la letra 'x'.
let res = str.replace(/a.+x/g, '!');
Esperamos que como resultado en la variable
se almacene la cadena '! zzz x kkk'. Sin embargo,
no es así - en la variable se obtiene la cadena
'! kkk'.
El problema es que nuestra expresión regular busca todos
los caracteres desde la letra 'a' hasta la letra 'x'.
¡Pero en nuestra cadena hay dos letras 'x'! Debido a
la avaricia, resulta que la expresión regular busca hasta
la última 'x', capturando así
algo diferente a lo que esperábamos.
Por supuesto, a menudo este comportamiento es precisamente el que necesitamos. Pero en este caso específico, nos gustaría desactivar la avaricia y decirle a la expresión regular que busque hasta la primera 'x'.
Para limitar la avaricia, hay que poner un signo de interrogación después del operador de repetición:
let res = str.replace(/a.+?x/g, '!');
La avaricia se puede limitar a todos los operadores
de repetición: tanto *, como ?, y {}
- de esta manera: *?, ?? y {}?.
Se da la cadena:
let str = 'aba accca azzza wwwwa';
Escriba una expresión regular que encuentre todas las cadenas
en cuyos extremos haya letras 'a',
y reemplace cada una de ellas por '!'. Entre
las letras 'a' puede haber cualquier carácter (excepto
'a').