From fa86bbd1b7d8ae5cc3abfab99a6f4a66a8ced5c8 Mon Sep 17 00:00:00 2001 From: joaquinelio Date: Mon, 15 Feb 2021 19:42:24 -0300 Subject: [PATCH 1/2] sticky --- .../16-regexp-sticky/article.md | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/9-regular-expressions/16-regexp-sticky/article.md b/9-regular-expressions/16-regexp-sticky/article.md index 476410cd3..67bf7ddbc 100644 --- a/9-regular-expressions/16-regexp-sticky/article.md +++ b/9-regular-expressions/16-regexp-sticky/article.md @@ -3,11 +3,9 @@ EL indicador `pattern:y` permite realizar la búsqueda en una posición dada en el string de origen. -Para entender el caso de uso del indicador `pattern:y`, y ver lo notable que es, exploremos un ejemplo práctico. +Para entender el caso de uso del indicador `pattern:y` exploremos un ejemplo práctico. -Una tarea común para regexps es el "Análisis léxico": tenemos un texto, por ej. en un lenguaje de programación, y analiza sus elementos estructurales. - -Por ejemplo, HTML tiene etiquetas y atributos, el código JavaScript tiene funciones, variables, etc. +Una tarea común para regexps es el "Análisis léxico": tenemos un texto, por ej. en un lenguaje de programación, y analiza sus elementos estructurales. Por ejemplo, HTML tiene etiquetas y atributos, el código JavaScript tiene funciones, variables, etc. Escribir analizadores léxicos es un área especial, con sus propias herramientas y algoritmos, así que no profundizaremos en ello; pero existe una tarea común: leer algo en una posición dada. @@ -15,41 +13,42 @@ Por ej. tenemos una cadena de código `subject:let varName = "value"`, y necesit Buscaremos el nombre de la variable usando regexp `pattern:\w+`. En realidad, el nombre de la variable de JavaScript necesita un regexp un poco más complejo para un emparejamiento más preciso, pero aquí eso no importa. -Una llamada a `str.match(/\w+/)` solo encontrará la primera palabra de la línea, o todas las palabras con el indicador `pattern:g`. Pero solo necesitamos una palabra en la posición `4`. +Una llamada a `str.match(/\w+/)` solo encontrará la primera palabra de la línea (`let`). No es la que queremos. +Podemos añadir el indicador `pattern:g`, pero llamando a `str.match(/\w+/g)` buscará todas las palabras del texto y solo necesitamos una palabra en la posición `4`. De nuevo, no es lo que necesitamos. + +**Entonces, ¿cómo buscamos exactamente en un posición deterninada?** -Para buscar desde la posición dada, usamos el método `regexp.exec(str)`. +Usemos el método `regexp.exec(str)`. -Sí `regexp` no tiene indicadores `pattern:g` o `pattern:y`, entonces este método busca la primera coincidencia en el string `str`, exactamente como `str.match(regexp)`. Un caso tan simple sin indicadores no nos interesa aquí. +Para un `regexp` sin los indicadores `pattern:g` y `pattern:y`, este método busca la primera coincidencia y funciona exactamente igual a `str.match(regexp)`. -Si existe el indicador `pattern:g`, realiza la búsqueda en el string `str` empezando desde la posición almacenada en su propiedad `regexp.lastIndex`. Y si encuentra una coincidencia, establece `regexp.lastIndex` en el index inmediatamente después del emparejamiento. +...Pero si existe el indicador `pattern:g`, realiza la búsqueda en el string `str` empezando desde la posición almacenada en su propiedad `regexp.lastIndex`. Y si encuentra una coincidencia, establece `regexp.lastIndex` en el index inmediatamente posterior a la coincidencia. -Cuando un regex es creado, su `lastIndex` es `0`. +En otras palabras, `regexp.lastIndex` funciona como punto de partida para la búsqueda, cada llamada lo reestablece a un nuevo valor: el posterior a la última coincidencia. Entonces, llamadas sucesivas a `regexp.exec(str)` devuelve coincidencias una después de la otra. Un ejemplo (con el indicador `pattern:g`): ```js run -let str = 'let varName'; - +let str = 'let varName'; // encontremos todas las palabras del string let regexp = /\w+/g; + alert(regexp.lastIndex); // 0 (inicialmente lastIndex=0) let word1 = regexp.exec(str); alert(word1[0]); // let (primera palabra) -alert(regexp.lastIndex); // 3 (Posición posterior al emparejamiento) +alert(regexp.lastIndex); // 3 (Posición posterior a la coincidencia) let word2 = regexp.exec(str); alert(word2[0]); // varName (2da palabra) -alert(regexp.lastIndex); // 11 (Posición posterior al emparejamiento) +alert(regexp.lastIndex); // 11 (Posición posterior a la coincidencia) let word3 = regexp.exec(str); -alert(word3); // null (no más emparejamientos) -alert(regexp.lastIndex); // 0 (reinicia en el final de la búsqueda) +alert(word3); // null (no más coincidencias) +alert(regexp.lastIndex); // 0 (se reinicia al final de la búsqueda) ``` -Cada coincidencia es devuelta como un array con grupos y propiedades adicionales. - Podemos conseguir todas las coincidencias en el loop: ```js run @@ -65,11 +64,13 @@ while (result = regexp.exec(str)) { } ``` -Tal uso de `regexp.exec` es una alternativa al método `str.match bAll`. +Tal uso de `regexp.exec` es una alternativa al método `str.match bAll`, con más control sobre el proceso. -A diferencia de otros métodos, podemos establecer nuestro propio `lastIndex`, para comenzar la búsqueda desde la posición dada. +Volvamos a nuestra tarea. -Por ejemplo, encontremos una palabra, comenzando desde la posición `4`: +Podemos estableceer manualmente `lastIndex` a `4`, para comenzar la búsqueda desde la posición dada. + +Como aquí: ```js run let str = 'let varName = "value"'; @@ -84,8 +85,14 @@ let word = regexp.exec(str); alert(word); // varName ``` +¡Problema resuelto! + Realizamos una búsqueda de `pattern:\w+`, comenzando desde la posición `regexp.lastIndex = 4`. +El resultado es correcto. + +...Pero espera, no tan rápido. + Nota que la búsqueda comienza en la posición `lastIndex` y luego sigue adelante. Si no hay ninguna palabra en la posición `lastIndex` pero la hay en algún lugar posterior, entonces será encontrada: ```js run @@ -94,17 +101,19 @@ let str = 'let varName = "value"'; let regexp = /\w+/g; *!* +// comenzando desde la posición 3 regexp.lastIndex = 3; */!* let word = regexp.exec(str); +// encuentra coincidencia en la posición 4 alert(word[0]); // varName alert(word.index); // 4 ``` -...Así que, con la propiedad `lastIndex` del indicador `pattern:g` se establece la posición inicial de la búsqueda. +Para algunas tareas, incluido el análisis léxico, esto está mal. Necesitamos la coincidencia en la posición exacta, y para ello es el flag `y`. -**El indicador `pattern:y` hace que `regexp.exec` busque exactamente en la posición `lastIndex`, ni antes ni después.** +**El indicador `pattern:y` hace que `regexp.exec` busque "exactamente en" la posición `lastIndex`, no "comenzando en" ella.** Aquí está la misma búsqueda con el indicador `pattern:y`: @@ -122,6 +131,8 @@ alert( regexp.exec(str) ); // varName (Una palabra en la posición 4) Como podemos ver, el `pattern:/\w+/y` de regexp no coincide en la posición `3` (a diferencia del indicador `pattern:g`), pero coincide en la posición `4`. +No solamente es lo que necesitamos, el uso del indicador `pattern:y` mejora el rendimiento. + Imagina que tenemos un texto largo, y no hay coincidencias en él. Entonces la búsqueda con el indicador `pattern:g` irá hasta el final del texto, y esto tomará significativamente más tiempo que la búsqueda con el indicador `pattern:y`. En tareas tales como el análisis léxico, normalmente hay muchas búsquedas en una posición exacta. Usar el indicador `pattern:y` es la clave para un buen desempeño. From 37bde37340262d27d644af17ffc083ca9168da39 Mon Sep 17 00:00:00 2001 From: joaquinelio Date: Mon, 15 Feb 2021 20:01:45 -0300 Subject: [PATCH 2/2] Update article.md --- 9-regular-expressions/16-regexp-sticky/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/9-regular-expressions/16-regexp-sticky/article.md b/9-regular-expressions/16-regexp-sticky/article.md index 67bf7ddbc..9c6a0e377 100644 --- a/9-regular-expressions/16-regexp-sticky/article.md +++ b/9-regular-expressions/16-regexp-sticky/article.md @@ -5,7 +5,7 @@ EL indicador `pattern:y` permite realizar la búsqueda en una posición dada en Para entender el caso de uso del indicador `pattern:y` exploremos un ejemplo práctico. -Una tarea común para regexps es el "Análisis léxico": tenemos un texto, por ej. en un lenguaje de programación, y analiza sus elementos estructurales. Por ejemplo, HTML tiene etiquetas y atributos, el código JavaScript tiene funciones, variables, etc. +Una tarea común para regexps es el "Análisis léxico": tomar un texto (como el de un lenguaje de programación), y analizar sus elementos estructurales. Por ejemplo, HTML tiene etiquetas y atributos, el código JavaScript tiene funciones, variables, etc. Escribir analizadores léxicos es un área especial, con sus propias herramientas y algoritmos, así que no profundizaremos en ello; pero existe una tarea común: leer algo en una posición dada. @@ -14,7 +14,7 @@ Por ej. tenemos una cadena de código `subject:let varName = "value"`, y necesit Buscaremos el nombre de la variable usando regexp `pattern:\w+`. En realidad, el nombre de la variable de JavaScript necesita un regexp un poco más complejo para un emparejamiento más preciso, pero aquí eso no importa. Una llamada a `str.match(/\w+/)` solo encontrará la primera palabra de la línea (`let`). No es la que queremos. -Podemos añadir el indicador `pattern:g`, pero llamando a `str.match(/\w+/g)` buscará todas las palabras del texto y solo necesitamos una palabra en la posición `4`. De nuevo, no es lo que necesitamos. +Podríamos añadir el indicador `pattern:g`, pero al llamar a `str.match(/\w+/g)` buscará todas las palabras del texto y solo necesitamos una y en la posición `4`. De nuevo, no es lo que necesitamos. **Entonces, ¿cómo buscamos exactamente en un posición deterninada?** @@ -22,7 +22,7 @@ Usemos el método `regexp.exec(str)`. Para un `regexp` sin los indicadores `pattern:g` y `pattern:y`, este método busca la primera coincidencia y funciona exactamente igual a `str.match(regexp)`. -...Pero si existe el indicador `pattern:g`, realiza la búsqueda en el string `str` empezando desde la posición almacenada en su propiedad `regexp.lastIndex`. Y si encuentra una coincidencia, establece `regexp.lastIndex` en el index inmediatamente posterior a la coincidencia. +...Pero si existe el indicador `pattern:g`, realiza la búsqueda en `str` empezando desde la posición almacenada en su propiedad `regexp.lastIndex`. Y si encuentra una coincidencia, establece `regexp.lastIndex` en el index inmediatamente posterior a la coincidencia. En otras palabras, `regexp.lastIndex` funciona como punto de partida para la búsqueda, cada llamada lo reestablece a un nuevo valor: el posterior a la última coincidencia. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy