validate test regulares regular online one generate from expresiones regex capturing-group regex-group

regex - test - ¿Qué es un grupo que no captura? ¿Que es lo que hace?



test expresiones regulares javascript (14)

Abra su Google Chrome devTools y luego la pestaña Consola: y escriba esto:

"Peace".match(/(/w)(/w)(/w)/)

Ejecútalo y verás:

["Pea", "P", "e", "a", index: 0, input: "Peace", groups: undefined]

El motor RegExp de JavaScript captura tres grupos, los elementos con índices 1,2,3. Ahora use la marca de no captura para ver el resultado.

"Peace".match(/(?:/w)(/w)(/w)/)

El resultado es:

["Pea", "e", "a", index: 0, input: "Peace", groups: undefined]

Esto es obvio lo que es el grupo no captura.

¿Cómo ?: Se usa y para qué sirve?


Bueno, yo soy un desarrollador de JavaScript y trataré de explicar su importancia en relación con JavaScript.

Considere un escenario en el que desea que el cat is animal igual a un cat is animal cuando le gustaría unir un gato y un animal, y ambos deben tener un is entre ellos.

// this will ignore "is" as that''s is what we want "cat is animal".match(/(cat)(?: is )(animal)/) ; result ["cat is animal", "cat", "animal"] // using lookahead pattern it will match only "cat" we can // use lookahead but the problem is we can not give anything // at the back of lookahead pattern "cat is animal".match(/cat(?= is animal)/) ; result ["cat"] //so I gave another grouping parenthesis for animal // in lookahead pattern to match animal as well "cat is animal".match(/(cat)(?= is (animal))/) ; result ["cat", "cat", "animal"] // we got extra cat in above example so removing another grouping "cat is animal".match(/cat(?= is (animal))/) ; result ["cat", "animal"]


Creo que le daría la respuesta, No use variables de captura sin verificar que la coincidencia haya tenido éxito.

Las variables de captura, $ 1, etc., no son válidas a menos que la coincidencia haya tenido éxito, y tampoco se borran.

#!/usr/bin/perl use warnings; use strict; $_ = "bronto saurus burger"; if (/(?:bronto)? saurus (steak|burger)/) { print "Fred wants a $1"; } else { print "Fred dont wants a $1 $2"; }

En el ejemplo anterior, para evitar la captura de bronto en $ 1, se usa (? :). Si el patrón coincide, entonces $ 1 se captura como el siguiente patrón agrupado. Por lo tanto, la salida será la siguiente:

Fred wants a burger

Es útil si no desea guardar las coincidencias.


Déjame intentarlo con un ejemplo:

Código Regex: - (?:animal)(?:=)(/w+)(,)/1/2

Cadena de búsqueda :-

Línea 1 - animal=cat,dog,cat,tiger,dog

Línea 2 - animal=cat,cat,dog,dog,tiger

Línea 3 - animal=dog,dog,cat,cat,tiger

(?:animal) -> Grupo 1 no capturado

(?:=) -> Grupo 2 no capturado

(/w+) -> Grupo capturado 1

(,) -> Grupo capturado 2

/1 -> resultado del grupo 1 capturado, es decir, en la línea 1 es cat, en la línea 2 es cat, en la línea 3 es dog.

/2 -> resultado del grupo 2 capturado, es decir, coma (,)

Entonces, en este código, dando / 1 y / 2 recordamos o repetimos el resultado de los grupos 1 y 2 capturados, respectivamente, más adelante en el código.

Según el orden del código (?: Animal) debe ser el grupo 1 y (?: =) Debe ser el grupo 2 y continúa ..

pero al dar el?: hacemos que el grupo de coincidencias no se capture (que no se cuenta en el grupo coincidente, por lo que el número de agrupación comienza desde el primer grupo capturado y no el no capturado), de modo que la repetición del resultado de la coincidencia -grupo (?: animal) no se puede llamar más tarde en el código.

Espero que esto explique el uso del grupo no captura.

introduzca la descripción de la imagen aquí


Déjame tratar de explicar esto con un ejemplo.

Considere el siguiente texto:

http://.com/ https://.com/questions/tagged/regex

Ahora, si aplico la expresión regular de abajo sobre ella ...

(https?|ftp)://([^//r/n]+)(/[^/r/n]*)?

... obtendría el siguiente resultado:

Match "http://.com/" Group 1: "http" Group 2: ".com" Group 3: "/" Match "https://.com/questions/tagged/regex" Group 1: "https" Group 2: ".com" Group 3: "/questions/tagged/regex"

Pero no me importa el protocolo, solo quiero el host y la ruta de la URL. Entonces, cambio la expresión regular para incluir el grupo que no captura (?:) .

(?:https?|ftp)://([^//r/n]+)(/[^/r/n]*)?

Ahora, mi resultado se ve así:

Match "http://.com/" Group 1: ".com" Group 2: "/" Match "https://.com/questions/tagged/regex" Group 1: ".com" Group 2: "/questions/tagged/regex"

¿Ver? El primer grupo no ha sido capturado. El analizador lo usa para hacer coincidir el texto, pero lo ignora más adelante, en el resultado final.

EDITAR:

Según lo solicitado, déjame tratar de explicar los grupos también.

Bueno, los grupos sirven para muchos propósitos. Pueden ayudarlo a extraer información exacta de una coincidencia más grande (que también se puede nombrar), le permiten volver a enfrentarse a un grupo coincidente anterior y pueden usarse para las sustituciones. Probemos algunos ejemplos, ¿de acuerdo?

Ok, imagine que tiene algún tipo de XML o HTML (tenga en cuenta que las expresiones regulares pueden no ser la mejor herramienta para el trabajo , pero es un buen ejemplo). Desea analizar las etiquetas para poder hacer algo como esto (he agregado espacios para que sea más fácil de entender):

/<(?<TAG>.+?)/> [^<]*? /<//k<TAG>/> or /<(.+?)/> [^<]*? /<//1/>

El primer regex tiene un grupo con nombre (TAG), mientras que el segundo usa un grupo común. Ambos regexes hacen lo mismo: usan el valor del primer grupo (el nombre de la etiqueta) para coincidir con la etiqueta de cierre. La diferencia es que el primero usa el nombre para coincidir con el valor, y el segundo usa el índice de grupo (que comienza en 1).

Probemos algunas sustituciones ahora. Considere el siguiente texto:

Lorem ipsum dolor sit amet consectetuer feugiat fames malesuada pretium egestas.

Ahora, vamos a usar este regex tonto sobre él:

/b(/S)(/S)(/S)(/S*)/b

Esta expresión regular combina palabras con al menos 3 caracteres y usa grupos para separar las primeras tres letras. El resultado es este:

Match "Lorem" Group 1: "L" Group 2: "o" Group 3: "r" Group 4: "em" Match "ipsum" Group 1: "i" Group 2: "p" Group 3: "s" Group 4: "um" ... Match "consectetuer" Group 1: "c" Group 2: "o" Group 3: "n" Group 4: "sectetuer" ...

Entonces, si aplicamos la cadena de sustitución ...

$1_$3$2_$4

... sobre esto, estamos tratando de usar el primer grupo, agregar un guión bajo, usar el tercer grupo, luego el segundo grupo, agregar otro guión bajo y luego el cuarto grupo. La cadena resultante sería como la de abajo.

L_ro_em i_sp_um d_lo_or s_ti_ a_em_t c_no_sectetuer f_ue_giat f_ma_es m_la_esuada p_er_tium e_eg_stas.

También puede usar grupos con nombre para las sustituciones, usando ${name} .

Para jugar con las expresiones regulares, recomiendo http://regex101.com/ , que ofrece una buena cantidad de detalles sobre cómo funciona la expresión regular; También ofrece algunos motores regex para elegir.


En expresiones regulares complejas, es posible que surja una situación en la que desee utilizar una gran cantidad de grupos, algunos de los cuales están disponibles para la coincidencia de repetición y otros para proporcionar referencias. De forma predeterminada, el texto que coincide con cada grupo se carga en la matriz de referencia inversa. Donde tenemos muchos grupos y solo necesitamos poder hacer referencia a algunos de ellos desde la matriz de referencia inversa, podemos anular este comportamiento predeterminado para indicar a la expresión regular que ciertos grupos están ahí solo para el manejo de la repetición y no es necesario capturarlos y almacenarlos. en la matriz de referencia inversa.


Hace que el grupo no capture, lo que significa que la subcadena que coincide con ese grupo no se incluirá en la lista de capturas. Un ejemplo en ruby ​​para ilustrar la diferencia:

"abc".match(/(.)(.)./).captures #=> ["a","b"] "abc".match(/(?:.)(.)./).captures #=> ["b"]


Los grupos que capturan se pueden usar más adelante en la expresión regular para coincidir O se pueden usar en la parte de reemplazo de la expresión regular. Hacer que un grupo que no capture no exime a ese grupo de ser usado por cualquiera de estas razones.

Los grupos que no capturan son excelentes si está intentando capturar muchas cosas diferentes y hay algunos grupos que no desea capturar.

Esa es la razón por la que existen. Mientras aprendes sobre grupos, aprende sobre grupos atómicos , ¡hacen mucho! También hay grupos de búsqueda, pero son un poco más complejos y no se usan mucho.

Ejemplo de uso posterior en la expresión regular (referencia inversa):

<([AZ][A-Z0-9]*)/b[^>]*>.*?<//1> [Encuentra una etiqueta xml (sin soporte ns)]

([AZ][A-Z0-9]*) es un grupo de captura (en este caso es el tagname)

Más adelante en la expresión regular es /1 que significa que solo coincidirá con el mismo texto que estaba en el primer grupo (el grupo ([AZ][A-Z0-9]*) ) (en este caso, coincide con la etiqueta final ).


MOTIVACIÓN HISTÓRICA: La existencia de grupos que no capturan puede explicarse con el uso de paréntesis. Considere las expresiones (a | b) c y a | bc, debido a la prioridad de concatenación sobre |, estas expresiones representan dos idiomas diferentes ({ac, bc} y {a, bc} respectivamente). Sin embargo, los paréntesis también se utilizan como un grupo coincidente (como se explica en las otras respuestas ...).

Cuando quiera tener paréntesis pero no capture la subexpresión, use GRUPOS NO CAPTORES. En el ejemplo, (?: A | b) c


No puedo comentar sobre las respuestas principales para decir esto: me gustaría agregar un punto explícito que solo está implícito en las respuestas principales:

El grupo que no captura (?...) no elimina ningún carácter de la coincidencia completa original, solo reorganiza visualmente la expresión regular para el programador.

Para acceder a una parte específica de la expresión regular sin caracteres extraños definidos, siempre necesitaría usar .group(<index>)


Puedes usar grupos de captura para organizar y analizar una expresión. Un grupo sin captura tiene el primer beneficio, pero no tiene la sobrecarga del segundo. Aún puedes decir que un grupo que no captura es opcional, por ejemplo.

Digamos que desea hacer coincidir el texto numérico, pero algunos números podrían escribirse como 1º, 2º, 3º, 4º, ... Si desea capturar la parte numérica, pero no el sufijo (opcional), puede usar un grupo que no capture. .

([0-9]+)(?:st|nd|rd|th)?

Eso coincidirá con los números en la forma 1, 2, 3 ... o en la forma 1, 2, 3, ... pero solo capturará la parte numérica.


Una cosa interesante que encontré es el hecho de que puede tener un grupo de captura dentro de un grupo que no captura. Echa un vistazo a las expresiones regulares de abajo para emparejar las URL:

var parse_url_regex = /^(?:([A-Za-z]+):)(//{0,3})([0-9./-A-Za-z]+)(?::(/d+))?(?://([^?#]*))?(?:/?([^#]*))?(?:#(.*))?$/;

Cadena de url de entrada:

var url = "http://www.ora.com:80/goodparts?q#fragment";

El primer grupo en mi expresión regular (?:([A-Za-z]+):) es un grupo sin captura que coincide con el esquema de protocolo y los dos puntos : carácter, es decir, http: pero cuando estaba ejecutando el código siguiente, estaba viendo el primer índice de la matriz devuelta contenía la cadena http cuando pensaba que http y dos puntos : ambos no se informarán porque están dentro de un grupo que no captura.

console.debug(parse_url_regex.exec(url));

Pensé que si el primer grupo (?:([A-Za-z]+):) es un grupo que no captura, entonces por qué está devolviendo la cadena http en la matriz de salida.

Por lo tanto, si observa que hay un grupo anidado ([A-Za-z]+) dentro del grupo que no captura. Ese grupo anidado ([A-Za-z]+) es un grupo de captura (que no tiene ?: Al principio) en sí mismo dentro de un grupo que no captura (?:([A-Za-z]+):) . Es por eso que el texto http aún se captura, pero el carácter de dos puntos que está dentro del grupo que no captura pero que está fuera del grupo de captura no se informa en la matriz de salida.


?: se utiliza cuando desea agrupar una expresión, pero no desea guardarla como una parte coincidente / capturada de la cadena.

Un ejemplo sería algo que coincida con una dirección IP:

/(?:/d{1,3}/.){3}/d{1,3}/

Tenga en cuenta que no me importa guardar los primeros 3 octetos, pero la agrupación (?:...) me permite acortar la expresión regular sin incurrir en la sobrecarga de capturar y almacenar una coincidencia.


tl; dr no captura los grupos, como su nombre indica son las partes de la expresión regular que no desea que se incluyan en la coincidencia y ?: es una forma de definir un grupo como no captura.

Digamos que tiene una dirección de correo electrónico [email protected] . La siguiente expresión regular creará dos grupos , la parte de identificación y la parte @ example.com. (/p{Alpha}*[az])(@example.com) . Para simplificar, estamos extrayendo el nombre de dominio completo, incluido el carácter @ .

Ahora digamos, solo necesitas la parte de identificación de la dirección. Lo que quiere hacer es tomar el primer grupo del resultado del partido, rodeado por () en la expresión regular y la forma de hacerlo es usar la sintaxis del grupo que no captura, es decir, ?: . Así que la expresión regular (/p{Alpha}*[az])(?:@example.com) devolverá solo la parte de identificación del correo electrónico.