diff --git a/9-regular-expressions/11-regexp-groups/01-test-mac/solution.md b/9-regular-expressions/11-regexp-groups/01-test-mac/solution.md index 26f7888f7..0082b2363 100644 --- a/9-regular-expressions/11-regexp-groups/01-test-mac/solution.md +++ b/9-regular-expressions/11-regexp-groups/01-test-mac/solution.md @@ -1,21 +1,21 @@ -A two-digit hex number is `pattern:[0-9a-f]{2}` (assuming the flag `pattern:i` is set). +Un número hexadecimal de dos dígitos es `pattern:[0-9a-f]{2}` (suponiendo que se ha establecido el indicador `pattern:i`). -We need that number `NN`, and then `:NN` repeated 5 times (more numbers); +Necesitamos ese número `NN`, y luego `:NN` repetido 5 veces (más números); -The regexp is: `pattern:[0-9a-f]{2}(:[0-9a-f]{2}){5}` +La expresión regular es: `pattern:[0-9a-f]{2}(:[0-9a-f]{2}){5}` -Now let's show that the match should capture all the text: start at the beginning and end at the end. That's done by wrapping the pattern in `pattern:^...$`. +Ahora demostremos que la coincidencia debe capturar todo el texto: comience por el principio y termine por el final. Eso se hace envolviendo el patrón en `pattern:^...$`. -Finally: +Finalmente: ```js run let regexp = /^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$/i; alert( regexp.test('01:32:54:67:89:AB') ); // true -alert( regexp.test('0132546789AB') ); // false (no colons) +alert( regexp.test('0132546789AB') ); // false (sin dos puntos) -alert( regexp.test('01:32:54:67:89') ); // false (5 numbers, need 6) +alert( regexp.test('01:32:54:67:89') ); // false (5 números, necesita 6) -alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ in the end) +alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ al final) ``` diff --git a/9-regular-expressions/11-regexp-groups/01-test-mac/task.md b/9-regular-expressions/11-regexp-groups/01-test-mac/task.md index 029a4803a..e2461b3b8 100644 --- a/9-regular-expressions/11-regexp-groups/01-test-mac/task.md +++ b/9-regular-expressions/11-regexp-groups/01-test-mac/task.md @@ -1,20 +1,20 @@ -# Check MAC-address +# Verificar dirección MAC -[MAC-address](https://en.wikipedia.org/wiki/MAC_address) of a network interface consists of 6 two-digit hex numbers separated by a colon. +La [Dirección MAC](https://es.wikipedia.org/wiki/Direcci%C3%B3n_MAC) de una interfaz de red consiste en 6 números hexadecimales de dos dígitos separados por dos puntos. -For instance: `subject:'01:32:54:67:89:AB'`. +Por ejemplo: `subject:'01:32:54:67:89:AB'`. -Write a regexp that checks whether a string is MAC-address. +Escriba una expresión regular que verifique si una cadena es una Dirección MAC. -Usage: +Uso: ```js let regexp = /your regexp/; alert( regexp.test('01:32:54:67:89:AB') ); // true -alert( regexp.test('0132546789AB') ); // false (no colons) +alert( regexp.test('0132546789AB') ); // false (sin dos puntos) -alert( regexp.test('01:32:54:67:89') ); // false (5 numbers, must be 6) +alert( regexp.test('01:32:54:67:89') ); // false (5 números, necesita 6) -alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ ad the end) +alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ al final) ``` diff --git a/9-regular-expressions/11-regexp-groups/02-find-webcolor-3-or-6/solution.md b/9-regular-expressions/11-regexp-groups/02-find-webcolor-3-or-6/solution.md index 0806dc4fd..426ea8ec8 100644 --- a/9-regular-expressions/11-regexp-groups/02-find-webcolor-3-or-6/solution.md +++ b/9-regular-expressions/11-regexp-groups/02-find-webcolor-3-or-6/solution.md @@ -1,12 +1,12 @@ -A regexp to search 3-digit color `#abc`: `pattern:/#[a-f0-9]{3}/i`. +Una expresión regular para buscar colores de 3 dígitos `#abc`: `pattern:/#[a-f0-9]{3}/i`. -We can add exactly 3 more optional hex digits. We don't need more or less. The color has either 3 or 6 digits. +Podemos agregar exactamente 3 dígitos hexadecimales opcionales más. No necesitamos más ni menos. El color tiene 3 o 6 dígitos. -Let's use the quantifier `pattern:{1,2}` for that: we'll have `pattern:/#([a-f0-9]{3}){1,2}/i`. +Utilizemos el cuantificador `pattern:{1,2}` para esto: llegaremos a `pattern:/#([a-f0-9]{3}){1,2}/i`. -Here the pattern `pattern:[a-f0-9]{3}` is enclosed in parentheses to apply the quantifier `pattern:{1,2}`. +Aquí el patrón `pattern:[a-f0-9]{3}` está rodeado en paréntesis para aplicar el cuantificador `pattern:{1,2}`. -In action: +En acción: ```js run let regexp = /#([a-f0-9]{3}){1,2}/gi; @@ -16,7 +16,7 @@ let str = "color: #3f3; background-color: #AA00ef; and: #abcd"; alert( str.match(regexp) ); // #3f3 #AA00ef #abc ``` -There's a minor problem here: the pattern found `match:#abc` in `subject:#abcd`. To prevent that we can add `pattern:\b` to the end: +Hay un pequeño problema aquí: el patrón encontrado `match:#abc` en `subject:#abcd`. Para prevenir esto podemos agregar `pattern:\b` al final: ```js run let regexp = /#([a-f0-9]{3}){1,2}\b/gi; diff --git a/9-regular-expressions/11-regexp-groups/02-find-webcolor-3-or-6/task.md b/9-regular-expressions/11-regexp-groups/02-find-webcolor-3-or-6/task.md index 09108484a..5b838c06a 100644 --- a/9-regular-expressions/11-regexp-groups/02-find-webcolor-3-or-6/task.md +++ b/9-regular-expressions/11-regexp-groups/02-find-webcolor-3-or-6/task.md @@ -1,8 +1,8 @@ -# Find color in the format #abc or #abcdef +# Encuentra el color en el formato #abc o #abcdef -Write a RegExp that matches colors in the format `#abc` or `#abcdef`. That is: `#` followed by 3 or 6 hexadecimal digits. +Escriba una expresión regular que haga coincidir los colores en el formato `#abc` o `#abcdef`. Esto es: `#` seguido por 3 o 6 dígitos hexadecimales. -Usage example: +Ejemplo del uso: ```js let regexp = /your regexp/g; @@ -11,4 +11,4 @@ let str = "color: #3f3; background-color: #AA00ef; and: #abcd"; alert( str.match(regexp) ); // #3f3 #AA00ef ``` -P.S. This should be exactly 3 or 6 hex digits. Values with 4 digits, such as `#abcd`, should not match. +P.D. Esto debe ser exactamente 3 o 6 dígitos hexadecimales. Valores con 4 dígitos, tales como `#abcd`, no deben coincidir. diff --git a/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/solution.md b/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/solution.md index c4349f9a0..5646137d9 100644 --- a/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/solution.md +++ b/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/solution.md @@ -1,6 +1,6 @@ -A positive number with an optional decimal part is (per previous task): `pattern:\d+(\.\d+)?`. +Un número positivo con una parte decimal opcional es (de acuerdo a la tarea anterior): `pattern:\d+(\.\d+)?`. -Let's add the optional `pattern:-` in the beginning: +Agreguemos el opcional al comienzo `pattern:-`: ```js run let regexp = /-?\d+(\.\d+)?/g; diff --git a/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/task.md b/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/task.md index 4f5a73fff..317167d80 100644 --- a/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/task.md +++ b/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/task.md @@ -1,8 +1,8 @@ -# Find all numbers +# Encuentre todos los números -Write a regexp that looks for all decimal numbers including integer ones, with the floating point and negative ones. +Escribe una expresión regular que busque todos los números decimales, incluidos los enteros, con el punto flotante y los negativos. -An example of use: +Un ejemplo de uso: ```js let regexp = /your regexp/g; diff --git a/9-regular-expressions/11-regexp-groups/04-parse-expression/solution.md b/9-regular-expressions/11-regexp-groups/04-parse-expression/solution.md index 130c57be3..f5cf2340f 100644 --- a/9-regular-expressions/11-regexp-groups/04-parse-expression/solution.md +++ b/9-regular-expressions/11-regexp-groups/04-parse-expression/solution.md @@ -1,21 +1,21 @@ -A regexp for a number is: `pattern:-?\d+(\.\d+)?`. We created it in previous tasks. +Una expresión regular para un número es: `pattern:-?\d+(\.\d+)?`. La creamos en tareas anteriores. -An operator is `pattern:[-+*/]`. The hyphen `pattern:-` goes first in the square brackets, because in the middle it would mean a character range, while we just want a character `-`. +Un operador es `pattern:[-+*/]`. El guión `pattern:-` va primero dentro de los corchetes porque colocado en el medio significaría un rango de caracteres, cuando nosotros queremos solamente un carácter `-`. -The slash `/` should be escaped inside a JavaScript regexp `pattern:/.../`, we'll do that later. +La barra inclinada `/` debe ser escapada dentro de una expresión regular de JavaScript `pattern:/.../`, eso lo haremos más tarde. -We need a number, an operator, and then another number. And optional spaces between them. +Necesitamos un número, un operador y luego otro número. Y espacios opcionales entre ellos. -The full regular expression: `pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`. +La expresión regular completa: `pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`. -It has 3 parts, with `pattern:\s*` between them: -1. `pattern:-?\d+(\.\d+)?` - the first number, -1. `pattern:[-+*/]` - the operator, -1. `pattern:-?\d+(\.\d+)?` - the second number. +Tiene 3 partes, con `pattern:\s*` en medio de ellas: +1. `pattern:-?\d+(\.\d+)?` - el primer número, +1. `pattern:[-+*/]` - el operador, +1. `pattern:-?\d+(\.\d+)?` - el segundo número. -To make each of these parts a separate element of the result array, let's enclose them in parentheses: `pattern:(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)`. +Para hacer que cada una de estas partes sea un elemento separado del array de resultados, encerrémoslas entre paréntesis: `pattern:(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)`. -In action: +En acción: ```js run let regexp = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/; @@ -23,22 +23,22 @@ let regexp = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/; alert( "1.2 + 12".match(regexp) ); ``` -The result includes: +El resultado incluye: -- `result[0] == "1.2 + 12"` (full match) -- `result[1] == "1.2"` (first group `(-?\d+(\.\d+)?)` -- the first number, including the decimal part) -- `result[2] == ".2"` (second group`(\.\d+)?` -- the first decimal part) -- `result[3] == "+"` (third group `([-+*\/])` -- the operator) -- `result[4] == "12"` (forth group `(-?\d+(\.\d+)?)` -- the second number) -- `result[5] == undefined` (fifth group `(\.\d+)?` -- the last decimal part is absent, so it's undefined) +- `result[0] == "1.2 + 12"` (coincidencia completa) +- `result[1] == "1.2"` (primer grupo `(-?\d+(\.\d+)?)` -- el primer número, incluyendo la parte decimal) +- `result[2] == ".2"` (segundo grupo `(\.\d+)?` -- la primera parte decimal) +- `result[3] == "+"` (tercer grupo `([-+*\/])` -- el operador) +- `result[4] == "12"` (cuarto grupo `(-?\d+(\.\d+)?)` -- el segundo número) +- `result[5] == undefined` (quinto grupo `(\.\d+)?` -- la última parte decimal no está presente, por lo tanto es indefinida) -We only want the numbers and the operator, without the full match or the decimal parts, so let's "clean" the result a bit. +Solo queremos los números y el operador, sin la coincidencia completa o las partes decimales, así que "limpiemos" un poco el resultado. -The full match (the arrays first item) can be removed by shifting the array `result.shift()`. +La coincidencia completa (el primer elemento del array) se puede eliminar cambiando el array `result.shift()`. -Groups that contain decimal parts (number 2 and 4) `pattern:(.\d+)` can be excluded by adding `pattern:?:` to the beginning: `pattern:(?:\.\d+)?`. +Los grupos que contengan partes decimales (número 2 y 4) `pattern:(.\d+)` pueden ser excluídos al agregar `pattern:?:` al comienzo: `pattern:(?:\.\d+)?`. -The final solution: +La solución final: ```js run function parse(expr) { diff --git a/9-regular-expressions/11-regexp-groups/04-parse-expression/task.md b/9-regular-expressions/11-regexp-groups/04-parse-expression/task.md index 8b54d4683..001204921 100644 --- a/9-regular-expressions/11-regexp-groups/04-parse-expression/task.md +++ b/9-regular-expressions/11-regexp-groups/04-parse-expression/task.md @@ -1,23 +1,23 @@ -# Parse an expression +# Analizar una expresión: -An arithmetical expression consists of 2 numbers and an operator between them, for instance: +Una expresión aritmética consta de 2 números y un operador entre ellos, por ejemplo: - `1 + 2` - `1.2 * 3.4` - `-3 / -6` - `-2 - 2` -The operator is one of: `"+"`, `"-"`, `"*"` or `"/"`. +El operador es uno de estos: `"+"`, `"-"`, `"*"` o `"/"`. -There may be extra spaces at the beginning, at the end or between the parts. +Puede haber espacios adicionales al principio, al final o entre las partes. -Create a function `parse(expr)` that takes an expression and returns an array of 3 items: +Crea una función `parse(expr)` que tome una expresión y devuelva un array de 3 ítems: -1. The first number. -2. The operator. -3. The second number. +1. El primer número. +2. El operador. +3. El segundo número. -For example: +Por ejemplo: ```js let [a, op, b] = parse("1.2 * 3.4"); diff --git a/9-regular-expressions/11-regexp-groups/article.md b/9-regular-expressions/11-regexp-groups/article.md index e559fd87c..deb676bcf 100644 --- a/9-regular-expressions/11-regexp-groups/article.md +++ b/9-regular-expressions/11-regexp-groups/article.md @@ -1,31 +1,31 @@ -# Capturing groups +# Grupos de captura -A part of a pattern can be enclosed in parentheses `pattern:(...)`. This is called a "capturing group". +Una parte de un patrón se puede incluir entre paréntesis `pattern:(...)`. Esto se llama "grupo de captura". -That has two effects: +Esto tiene dos resultados: -1. It allows to get a part of the match as a separate item in the result array. -2. If we put a quantifier after the parentheses, it applies to the parentheses as a whole. +1. Permite obtener una parte de la coincidencia como un elemento separado en la matriz de resultados. +2. Si colocamos un cuantificador después del paréntesis, se aplica a los paréntesis en su conjunto. -## Examples +## Ejemplos -Let's see how parentheses work in examples. +Veamos cómo funcionan los paréntesis en los ejemplos. -### Example: gogogo +### Ejemplo: gogogo -Without parentheses, the pattern `pattern:go+` means `subject:g` character, followed by `subject:o` repeated one or more times. For instance, `match:goooo` or `match:gooooooooo`. +Sin paréntesis, el patrón `pattern:go+` significa el carácter `subject:g`, seguido por `subject:o` repetido una o más veces. Por ejemplo, `match:goooo` o `match:gooooooooo`. -Parentheses group characters together, so `pattern:(go)+` means `match:go`, `match:gogo`, `match:gogogo` and so on. +Los paréntesis agrupan los carácteres juntos, por lo tanto `pattern:(go)+` significa `match:go`, `match:gogo`, `match:gogogo` etcétera. ```js run alert( 'Gogogo now!'.match(/(go)+/ig) ); // "Gogogo" ``` -### Example: domain +### Ejemplo: dominio -Let's make something more complex -- a regular expression to search for a website domain. +Hagamos algo más complejo: una expresión regular para buscar un dominio de sitio web. -For example: +Por ejemplo: ``` mail.com @@ -33,9 +33,9 @@ users.mail.com smith.users.mail.com ``` -As we can see, a domain consists of repeated words, a dot after each one except the last one. +Como podemos ver, un dominio consta de palabras repetidas, un punto después de cada una excepto la última. -In regular expressions that's `pattern:(\w+\.)+\w+`: +En expresiones regulares eso es `pattern:(\w+\.)+\w+`: ```js run let regexp = /(\w+\.)+\w+/g; @@ -43,17 +43,17 @@ let regexp = /(\w+\.)+\w+/g; alert( "site.com my.site.com".match(regexp) ); // site.com,my.site.com ``` -The search works, but the pattern can't match a domain with a hyphen, e.g. `my-site.com`, because the hyphen does not belong to class `pattern:\w`. +La búsqueda funciona, pero el patrón no puede coincidir con un dominio con un guión, por ejemplo, `my-site.com`, porque el guión no pertenece a la clase `pattern:\w`. -We can fix it by replacing `pattern:\w` with `pattern:[\w-]` in every word except the last one: `pattern:([\w-]+\.)+\w+`. +Podemos arreglarlo al reemplazar `pattern:\w` con `pattern:[\w-]` en cada palabra excepto el último: `pattern:([\w-]+\.)+\w+`. -### Example: email +### Ejemplo: email -The previous example can be extended. We can create a regular expression for emails based on it. +El ejemplo anterior puede ser extendido. Podemos crear una expresión regular para emails en base a esto. -The email format is: `name@domain`. Any word can be the name, hyphens and dots are allowed. In regular expressions that's `pattern:[-.\w]+`. +El formato de email es: `name@domain`. Cualquier palabra puede ser el nombre, no se permite guiones y puntos. En expresiones regulares esto es `pattern:[-.\w]+`. -The pattern: +El patrón: ```js run let regexp = /[-.\w]+@([\w-]+\.)+[\w-]+/g; @@ -61,24 +61,24 @@ let regexp = /[-.\w]+@([\w-]+\.)+[\w-]+/g; alert("my@mail.com @ his@site.com.uk".match(regexp)); // my@mail.com, his@site.com.uk ``` -That regexp is not perfect, but mostly works and helps to fix accidental mistypes. The only truly reliable check for an email can only be done by sending a letter. +Esa expresión regular no es perfecta, pero sobre todo funciona y ayuda a corregir errores de escritura accidentales. La única verificación verdaderamente confiable para un correo electrónico solo se puede realizar enviando una carta. -## Parentheses contents in the match +## Contenido del paréntesis en la coincidencia (match) -Parentheses are numbered from left to right. The search engine memorizes the content matched by each of them and allows to get it in the result. +Los paréntesis están numerados de izquierda a derecha. El buscador memoriza el contenido que coincide con cada uno de ellos y permite obtenerlo en el resultado. -The method `str.match(regexp)`, if `regexp` has no flag `g`, looks for the first match and returns it as an array: +El método `str.match(regexp)`, si `regexp` no tiene indicador (flag) `g`, busca la primera coincidencia y lo devuelve como un array: -1. At index `0`: the full match. -2. At index `1`: the contents of the first parentheses. -3. At index `2`: the contents of the second parentheses. -4. ...and so on... +1. En el índice `0`: la coincidencia completa. +2. En el índice `1`: el contenido del primer paréntesis. +3. En el índice `2`: el contenido del segundo paréntesis. +4. ...etcétera... -For instance, we'd like to find HTML tags `pattern:<.*?>`, and process them. It would be convenient to have tag content (what's inside the angles), in a separate variable. +Por ejemplo, nos gustaría encontrar etiquetas HTML `pattern:<.*?>`, y procesarlas. Sería conveniente tener el contenido de la etiqueta (lo que está dentro de los ángulos), en una variable por separado. -Let's wrap the inner content into parentheses, like this: `pattern:<(.*?)>`. +Envolvamos el contenido interior en paréntesis, de esta forma: `pattern:<(.*?)>`. -Now we'll get both the tag as a whole `match:

` and its contents `match:h1` in the resulting array: +Ahora obtendremos ambos, la etiqueta entera `match:

` y su contenido `match:h1` en el array resultante: ```js run let str = '

Hello, world!

'; @@ -89,23 +89,23 @@ alert( tag[0] ); //

alert( tag[1] ); // h1 ``` -### Nested groups +### Grupos anidados -Parentheses can be nested. In this case the numbering also goes from left to right. +Los paréntesis pueden ser anidados. En este caso la numeración también va de izquierda a derecha. -For instance, when searching a tag in `subject:` we may be interested in: +Por ejemplo, al buscar una etiqueta en `subject:` tal vez nos pueda interesar: -1. The tag content as a whole: `match:span class="my"`. -2. The tag name: `match:span`. -3. The tag attributes: `match:class="my"`. +1. El contenido de la etiqueta como un todo: `match:span class="my"`. +2. El nombre de la etiqueta: `match:span`. +3. Los atributos de la etiqueta: `match:class="my"`. -Let's add parentheses for them: `pattern:<(([a-z]+)\s*([^>]*))>`. +Agreguemos paréntesis: `pattern:<(([a-z]+)\s*([^>]*))>`. -Here's how they are numbered (left to right, by the opening paren): +Así es cómo se enumeran (izquierda a derecha, por el paréntesis de apertura): ![](regexp-nested-groups-pattern.svg) -In action: +En acción: ```js run let str = ''; @@ -119,59 +119,59 @@ alert(result[2]); // span alert(result[3]); // class="my" ``` -The zero index of `result` always holds the full match. +El índice cero de `result` siempre contiene la coincidencia completa. -Then groups, numbered from left to right by an opening paren. The first group is returned as `result[1]`. Here it encloses the whole tag content. +Luego los grupos, numerados de izquierda a derecha por un paréntesis de apertura. El primer grupo se devuelve como `result[1]`. Aquí se encierra todo el contenido de la etiqueta. -Then in `result[2]` goes the group from the second opening paren `pattern:([a-z]+)` - tag name, then in `result[3]` the tag: `pattern:([^>]*)`. +Luego en `result[2]` va el grupo desde el segundo paréntesis de apertura `pattern:([a-z]+)` - nombre de etiqueta, luego en `result[3]` la etiqueta: `pattern:([^>]*)`. -The contents of every group in the string: +El contenido de cada grupo en el string: ![](regexp-nested-groups-matches.svg) -### Optional groups +### Grupos opcionales -Even if a group is optional and doesn't exist in the match (e.g. has the quantifier `pattern:(...)?`), the corresponding `result` array item is present and equals `undefined`. +Incluso si un grupo es opcional y no existe en la coincidencia (p.ej. tiene el cuantificador `pattern:(...)?`), el elemento array `result` correspondiente está presente y es igual a `undefined`. -For instance, let's consider the regexp `pattern:a(z)?(c)?`. It looks for `"a"` optionally followed by `"z"` optionally followed by `"c"`. +Por ejemplo, consideremos la expresión regular `pattern:a(z)?(c)?`. Busca `"a"` seguida por opcionalmente `"z"`, seguido por `"c"` opcionalmente. -If we run it on the string with a single letter `subject:a`, then the result is: +Si lo ejecutamos en el string con una sola letra `subject:a`, entonces el resultado es: ```js run let match = 'a'.match(/a(z)?(c)?/); alert( match.length ); // 3 -alert( match[0] ); // a (whole match) +alert( match[0] ); // a (coincidencia completa) alert( match[1] ); // undefined alert( match[2] ); // undefined ``` -The array has the length of `3`, but all groups are empty. +El array tiene longitud de `3`, pero todos los grupos están vacíos. -And here's a more complex match for the string `subject:ac`: +Y aquí hay una coincidencia más compleja para el string `subject:ac`: ```js run let match = 'ac'.match(/a(z)?(c)?/) alert( match.length ); // 3 -alert( match[0] ); // ac (whole match) -alert( match[1] ); // undefined, because there's nothing for (z)? +alert( match[0] ); // ac (coincidencia completa) +alert( match[1] ); // undefined, ¿porque no hay nada para (z)? alert( match[2] ); // c ``` -The array length is permanent: `3`. But there's nothing for the group `pattern:(z)?`, so the result is `["ac", undefined, "c"]`. +La longitud del array es permanente: `3`. Pero no hay nada para el grupo `pattern:(z)?`, por lo tanto el resultado es `["ac", undefined, "c"]`. -## Searching for all matches with groups: matchAll +## Buscar todas las coincidencias con grupos: matchAll -```warn header="`matchAll` is a new method, polyfill may be needed" -The method `matchAll` is not supported in old browsers. +```warn header="`matchAll` es un nuevo método, polyfill puede ser necesario" +El método `matchAll` no es compatible con antiguos navegadores. -A polyfill may be required, such as . +Un polyfill puede ser requerido, tal como . ``` -When we search for all matches (flag `pattern:g`), the `match` method does not return contents for groups. +Cuando buscamos todas las coincidencias (flag `pattern:g`), el método `match` no devuelve contenido para los grupos. -For example, let's find all tags in a string: +Por ejemplo, encontremos todas las etiquetas en un string: ```js run let str = '

'; @@ -181,55 +181,55 @@ let tags = str.match(/<(.*?)>/g); alert( tags ); //

,

``` -The result is an array of matches, but without details about each of them. But in practice we usually need contents of capturing groups in the result. +El resultado es un array de coincidencias, pero sin detalles sobre cada uno de ellos. Pero en la práctica normalmente necesitamos contenidos de los grupos de captura en el resultado. -To get them, we should search using the method `str.matchAll(regexp)`. +Para obtenerlos tenemos que buscar utilizando el método `str.matchAll(regexp)`. -It was added to JavaScript language long after `match`, as its "new and improved version". +Fue incluido a JavaScript mucho después de `match`, como su versión "nueva y mejorada". -Just like `match`, it looks for matches, but there are 3 differences: +Al igual que `match`, busca coincidencias, pero hay 3 diferencias: -1. It returns not an array, but an iterable object. -2. When the flag `pattern:g` is present, it returns every match as an array with groups. -3. If there are no matches, it returns not `null`, but an empty iterable object. +1. No devuelve un array sino un objeto iterable. +2. Cuando está presente el indicador `pattern:g`, devuelve todas las coincidencias como un array con grupos. +3. Si no hay coincidencias, no devuelve `null` sino un objeto iterable vacío. -For instance: +Por ejemplo: ```js run let results = '

'.matchAll(/<(.*?)>/gi); -// results - is not an array, but an iterable object +// results - no es un array, sino un objeto iterable alert(results); // [object RegExp String Iterator] alert(results[0]); // undefined (*) -results = Array.from(results); // let's turn it into array +results = Array.from(results); // lo convirtamos en array -alert(results[0]); //

,h1 (1st tag) -alert(results[1]); //

,h2 (2nd tag) +alert(results[0]); //

,h1 (1er etiqueta) +alert(results[1]); //

,h2 (2da etiqueta) ``` -As we can see, the first difference is very important, as demonstrated in the line `(*)`. We can't get the match as `results[0]`, because that object isn't pseudoarray. We can turn it into a real `Array` using `Array.from`. There are more details about pseudoarrays and iterables in the article . +Como podemos ver, la primera diferencia es muy importante, como se demuestra en la línea `(*)`. No podemos obtener la coincidencia como `results[0]`, porque ese objeto no es pseudo array. Lo podemos convertir en un `Array` real utilizando `Array.from`. Hay más detalles sobre pseudo arrays e iterables en el artículo. . -There's no need in `Array.from` if we're looping over results: +No se necesita `Array.from` si estamos iterando sobre los resultados: ```js run let results = '

'.matchAll(/<(.*?)>/gi); for(let result of results) { alert(result); - // first alert:

,h1 - // second:

,h2 + // primer alert:

,h1 + // segundo:

,h2 } ``` -...Or using destructuring: +...O utilizando desestructurización: ```js let [tag1, tag2] = '

'.matchAll(/<(.*?)>/gi); ``` -Every match, returned by `matchAll`, has the same format as returned by `match` without flag `pattern:g`: it's an array with additional properties `index` (match index in the string) and `input` (source string): +Cada coincidencia devuelta por `matchAll` tiene el mismo formato que el devuelto por `match` sin el flag `pattern:g`: es un array con propiedades adicionales `index` (coincide índice en el string) e `input` (fuente string): ```js run let results = '

'.matchAll(/<(.*?)>/gi); @@ -242,23 +242,23 @@ alert( tag1.index ); // 0 alert( tag1.input ); //

``` -```smart header="Why is a result of `matchAll` an iterable object, not an array?" -Why is the method designed like that? The reason is simple - for the optimization. +```smart header="¿Por qué el resultado de `matchAll` es un objeto iterable y no un array?" +¿Por qué el método está diseñado de esa manera? La razón es simple - por la optimización. -The call to `matchAll` does not perform the search. Instead, it returns an iterable object, without the results initially. The search is performed each time we iterate over it, e.g. in the loop. +El llamado a `matchAll` no realiza la búsqueda. En cambio devuelve un objeto iterable, en un principio sin los resultados. La búsqueda es realizada cada vez que iteramos sobre ella, es decir, en el bucle. -So, there will be found as many results as needed, not more. +Por lo tanto, se encontrará tantos resultados como sea necesario, no más. -E.g. there are potentially 100 matches in the text, but in a `for..of` loop we found 5 of them, then decided it's enough and make a `break`. Then the engine won't spend time finding other 95 matches. +Por ejemplo, posiblemente hay 100 coincidencias en el texto, pero en un bucle `for..of` encontramos 5 de ellas: entonces decidimos que es suficiente y realizamos un `break`. Así el buscador no gastará tiempo buscando otras 95 coincidencias. ``` -## Named groups +## Grupos con nombre -Remembering groups by their numbers is hard. For simple patterns it's doable, but for more complex ones counting parentheses is inconvenient. We have a much better option: give names to parentheses. +Es difícil recordar a los grupos por su número. Para patrones simples, es factible, pero para los más complejos, contar los paréntesis es inconveniente. Tenemos una opción mucho mejor: poner nombres entre paréntesis. -That's done by putting `pattern:?` immediately after the opening paren. +Eso se hace poniendo `pattern:?` inmediatamente después del paréntesis de apertura. -For example, let's look for a date in the format "year-month-day": +Por ejemplo, busquemos una fecha en el formato "año-mes-día": ```js run *!* @@ -273,11 +273,11 @@ alert(groups.month); // 04 alert(groups.day); // 30 ``` -As you can see, the groups reside in the `.groups` property of the match. +Como puedes ver, los grupos residen en la propiedad `.groups` de la coincidencia. -To look for all dates, we can add flag `pattern:g`. +Para buscar todas las fechas, podemos agregar el flag `pattern:g`. -We'll also need `matchAll` to obtain full matches, together with groups: +También vamos a necesitar `matchAll` para obtener coincidencias completas, junto con los grupos: ```js run let dateRegexp = /(?[0-9]{4})-(?[0-9]{2})-(?[0-9]{2})/g; @@ -290,16 +290,16 @@ for(let result of results) { let {year, month, day} = result.groups; alert(`${day}.${month}.${year}`); - // first alert: 30.10.2019 - // second: 01.01.2020 + // primer alert: 30.10.2019 + // segundo: 01.01.2020 } ``` -## Capturing groups in replacement +## Grupos de captura en reemplazo -Method `str.replace(regexp, replacement)` that replaces all matches with `regexp` in `str` allows to use parentheses contents in the `replacement` string. That's done using `pattern:$n`, where `pattern:n` is the group number. +El método `str.replace(regexp, replacement)` que reemplaza todas las coincidencias con `regexp` en `str` nos permite utilizar el contenido de los paréntesis en el string `replacement`. Esto se hace utilizando `pattern:$n`, donde `pattern:n` es el número de grupo. -For example, +Por ejemplo, ```js run let str = "John Bull"; @@ -308,9 +308,9 @@ let regexp = /(\w+) (\w+)/; alert( str.replace(regexp, '$2, $1') ); // Bull, John ``` -For named parentheses the reference will be `pattern:$`. +Para los paréntesis con nombre la referencia será `pattern:$`. -For example, let's reformat dates from "year-month-day" to "day.month.year": +Por ejemplo, volvamos a darle formato a las fechas desde "year-month-day" a "day.month.year": ```js run let regexp = /(?[0-9]{4})-(?[0-9]{2})-(?[0-9]{2})/g; @@ -321,44 +321,44 @@ alert( str.replace(regexp, '$.$.$') ); // 30.10.2019, 01.01.2020 ``` -## Non-capturing groups with ?: +## Grupos que no capturan con ?: -Sometimes we need parentheses to correctly apply a quantifier, but we don't want their contents in results. +A veces necesitamos paréntesis para aplicar correctamente un cuantificador, pero no queremos su contenido en los resultados. -A group may be excluded by adding `pattern:?:` in the beginning. +Se puede excluir un grupo agregando `pattern:?:` al inicio. -For instance, if we want to find `pattern:(go)+`, but don't want the parentheses contents (`go`) as a separate array item, we can write: `pattern:(?:go)+`. +Por ejemplo, si queremos encontrar `pattern:(go)+`, pero no queremos el contenido del paréntesis (`go`) como un ítem separado del array, podemos escribir: `pattern:(?:go)+`. -In the example below we only get the name `match:John` as a separate member of the match: +En el ejemplo de arriba solamente obtenemos el nombre `match:John` como un miembro separado de la coincidencia: ```js run let str = "Gogogo John!"; *!* -// ?: exludes 'go' from capturing +// ?: excluye 'go' de la captura let regexp = /(?:go)+ (\w+)/i; */!* let result = str.match(regexp); -alert( result[0] ); // Gogogo John (full match) +alert( result[0] ); // Gogogo John (coincidencia completa) alert( result[1] ); // John -alert( result.length ); // 2 (no more items in the array) +alert( result.length ); // 2 (no hay más ítems en el array) ``` -## Summary +## Resumen -Parentheses group together a part of the regular expression, so that the quantifier applies to it as a whole. +Los paréntesis agrupan una parte de la expresión regular, de modo que el cuantificador se aplique a ella como un todo. -Parentheses groups are numbered left-to-right, and can optionally be named with `(?...)`. +Los grupos de paréntesis se numeran de izquierda a derecha y, opcionalmente, se pueden nombrar con `(?...)`. -The content, matched by a group, can be obtained in the results: +El contenido, emparejado por un grupo, se puede obtener en los resultados: -- The method `str.match` returns capturing groups only without flag `pattern:g`. -- The method `str.matchAll` always returns capturing groups. +- El método `str.match` devuelve grupos de captura únicamente sin el indicador (flag) `pattern:g`. +- El método `str.matchAll` siempre devuelve grupos de captura. -If the parentheses have no name, then their contents is available in the match array by its number. Named parentheses are also available in the property `groups`. +Si el paréntesis no tiene nombre, entonces su contenido está disponible en el array de coincidencias por su número. Los paréntesis con nombre también están disponible en la propiedad `groups`. -We can also use parentheses contents in the replacement string in `str.replace`: by the number `$n` or the name `$`. +También podemos utilizar el contenido del paréntesis en el string de reemplazo de `str.replace`: por el número `$n` o el nombre `$`. -A group may be excluded from numbering by adding `pattern:?:` in its start. That's used when we need to apply a quantifier to the whole group, but don't want it as a separate item in the results array. We also can't reference such parentheses in the replacement string. +Un grupo puede ser excluido de la enumeración al agregar `pattern:?:` en el inicio. Eso se usa cuando necesitamos aplicar un cuantificador a todo el grupo, pero no lo queremos como un elemento separado en el array de resultados. Tampoco podemos hacer referencia a tales paréntesis en el string de reemplazo.