Skip to content

Sticky flag "y", searching at position #424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Dec 17, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 38 additions & 38 deletions 9-regular-expressions/16-regexp-sticky/article.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,56 @@

# Sticky flag "y", searching at position
# Indicador adhesivo “y”, buscando en una posición.

The flag `pattern:y` allows to perform the search at the given position in the source string.
EL indicador `pattern:y` permite realizar la búsqueda en una posición dada en el string de origen.

To grasp the use case of `pattern:y` flag, and see how great it is, let's explore a practical use case.
Para entender el caso de uso del indicador `pattern:y`, y ver que tan bueno es, exploremos un caso práctico de uso.

One of common tasks for regexps is "lexical analysis": we get a text, e.g. in a programming language, and analyze it for structural elements.
Una tarea común para regexps es "Analisis lexico": tenemos un texto, por ej. en un lenguaje de programación, y analiza sus elementos estructurales.

For instance, HTML has tags and attributes, JavaScript code has functions, variables, and so on.
Por ejemplo, HTML tiene etiquetas y atributos, el código JavaScript tiene funciones, variables, etc.

Writing lexical analyzers is a special area, with its own tools and algorithms, so we don't go deep in there, but there's a common task: to read something at the given position.
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.

E.g. we have a code string `subject:let varName = "value"`, and we need to read the variable name from it, that starts at position `4`.
Por ej. tenemos una cadena de código `subject:let varName = "value"`, y necesitamos leer el nombre de su variable, que comienza en la posición `4`.

We'll look for variable name using regexp `pattern:\w+`. Actually, JavaScript variable names need a bit more complex regexp for accurate matching, but here it doesn't matter.
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.

A call to `str.match(/\w+/)` will find only the first word in the line. Or all words with the flag `pattern:g`. But we need only one word at position `4`.
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`.

To search from the given position, we can use method `regexp.exec(str)`.
Para buscar desde la posición dada, usamos el método `regexp.exec(str)`.

If the `regexp` doesn't have flags `pattern:g` or `pattern:y`, then this method looks for the first match in the string `str`, exactly like `str.match(regexp)`. Such simple no-flags case doesn't interest us here.
`regexp` no tiene indicadores `pattern:g` o `pattern:y`, entonces este método busca la primer coincidencia en el string `str`, exactamente como `str.match(regexp)`. Un caso tan simple sin indicadores no nos interesa aquí.

If there's flag `pattern:g`, then it performs the search in the string `str`, starting from position stored in its `regexp.lastIndex` property. And, if it finds a match, then sets `regexp.lastIndex` to the index immediately after the match.
Sí hay 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, entonces establece `regexp.lastIndex` en el index inmediatamente después del emparejamiento.

When a regexp is created, its `lastIndex` is `0`.
Cuando un regex es creado, su `lastIndex` es `0`.

So, successive calls to `regexp.exec(str)` return matches one after another.
Entonces, llamadas sucesivas a `regexp.exec(str)` devuelve coincidencias una después de la otra.

An example (with flag `pattern:g`):
Un ejemplo (con el indicador `pattern:g`):

```js run
let str = 'let varName';

let regexp = /\w+/g;
alert(regexp.lastIndex); // 0 (initially lastIndex=0)
alert(regexp.lastIndex); // 0 (inicialmente lastIndex=0)

let word1 = regexp.exec(str);
alert(word1[0]); // let (1st word)
alert(regexp.lastIndex); // 3 (position after the match)
alert(word1[0]); // let (1er palabra)
alert(regexp.lastIndex); // 3 (Posición posterior al emparejamiento)

let word2 = regexp.exec(str);
alert(word2[0]); // varName (2nd word)
alert(regexp.lastIndex); // 11 (position after the match)
alert(word2[0]); // varName (2da palabra)
alert(regexp.lastIndex); // 11 (Posición posterior al emparejamiento)

let word3 = regexp.exec(str);
alert(word3); // null (no more matches)
alert(regexp.lastIndex); // 0 (resets at search end)
alert(word3); // null (no más emparejamientos)
alert(regexp.lastIndex); // 0 (reinicia en el final de la búsqueda)
```

Every match is returned as an array with groups and additional properties.
Cada coincidencia es devuelta como un array con grupos y propiedades adicionales.

We can get all matches in the loop:
Podemos conseguir todas las coincidencias en el loop:

```js run
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

¿Podrias traducir comentarios lineas 63 64 ?
github no me deja sugerir ahi (dentro de un bloque sin traducir)

Quizas tambien la 62 pero con cuidado:

alert( Se encontró ${result[0]} en la posición ${result.index} );

let str = 'let varName';
Expand All @@ -65,16 +65,16 @@ while (result = regexp.exec(str)) {
}
```

Such use of `regexp.exec` is an alternative to method `str.matchAll`.
Tal uso de `regexp.exec` es una alternativa para el método `str.match bAll`.

Unlike other methods, we can set our own `lastIndex`, to start the search from the given position.
A diferencia de otros métodos, podemos establecer nuestro propio `lastIndex`, para comenzar la búsqueda desde la posición dada.

For instance, let's find a word, starting from position `4`:
Por ejemplo, encontremos una palabra, comenzando desde la posición `4`:

```js run
let str = 'let varName = "value"';

let regexp = /\w+/g; // without flag "g", property lastIndex is ignored
let regexp = /\w+/g; // Sin el indicador “g”, la propiedad lastindex es ignorada.

*!*
regexp.lastIndex = 4;
Expand All @@ -84,9 +84,9 @@ let word = regexp.exec(str);
alert(word); // varName
```

We performed a search of `pattern:\w+`, starting from position `regexp.lastIndex = 4`.
Realizamos una búsqueda de `pattern:\w+`, comenzando desde la posición `regexp.lastIndex = 4`.

Please note: the search starts at position `lastIndex` and then goes further. If there's no word at position `lastIndex`, but it's somewhere after it, then it will be found:
Por favor nota que la búsqueda comienza en la posición `lastIndex` y luego profundiza. Sí no hay ninguna palabra en la posición `lastIndex`, pero está en algún lugar posterior, entonces será encontrada:

```js run
let str = 'let varName = "value"';
Expand All @@ -102,26 +102,26 @@ alert(word[0]); // varName
alert(word.index); // 4
```

...So, with flag `pattern:g` property `lastIndex` sets the starting position for the search.
...Así que, con la propiedad `lastIndex` del indicador `pattern:g` se establece la posición inicial de la búsqueda.

**Flag `pattern:y` makes `regexp.exec` to look exactly at position `lastIndex`, not before, not after it.**
**El indicador `pattern:y` hace que `regexp.exec` busque exactamente en la posición `lastIndex`, ni antes ni después.**

Here's the same search with flag `pattern:y`:
Aquí está la misma búsqueda con el indicador `pattern:y`:

```js run
let str = 'let varName = "value"';

let regexp = /\w+/y;

regexp.lastIndex = 3;
alert( regexp.exec(str) ); // null (there's a space at position 3, not a word)
alert( regexp.exec(str) ); // null (Hay un espacio en la posición 3, no una palabra)

regexp.lastIndex = 4;
alert( regexp.exec(str) ); // varName (word at position 4)
alert( regexp.exec(str) ); // varName (Una palabra en la posición 4)
```

As we can see, regexp `pattern:/\w+/y` doesn't match at position `3` (unlike the flag `pattern:g`), but matches at position `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`.

Imagine, we have a long text, and there are no matches in it, at all. Then searching with flag `pattern:g` will go till the end of the text, and this will take significantly more time than the search with flag `pattern:y`.
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`.

In such tasks like lexical analysis, there are usually many searches at an exact position. Using flag `pattern:y` is the key for a good performance.
En tales tareas 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.