Buscar..


Lo esencial

Las referencias anteriores se utilizan para hacer coincidir el mismo texto que un grupo de captura coincidió previamente. Esto ayuda tanto a reutilizar partes anteriores de su patrón como a asegurar que dos partes de una cadena coinciden.

Por ejemplo, si está intentando verificar que una cadena tiene un dígito de cero a nueve, un separador, como guiones, barras o incluso espacios, una letra minúscula, otro separador, luego otro dígito de cero a nueve, podría use un regex como este:

[0-9][-/ ][a-z][-/ ][0-9]

Esto coincidiría con 1-a-4 , pero también coincidiría con 1-a/4 o 1 a-4 . Si queremos que los separadores coincidan, podemos usar un grupo de captura y una referencia posterior. La referencia posterior verá la coincidencia encontrada en el grupo de captura indicado y asegurará que la ubicación de la referencia posterior coincida exactamente.

Usando nuestro mismo ejemplo, la expresión regular se convertiría en:

[0-9]([-/ ])[a-z]\1[0-9]

El \1 denota el primer grupo de captura en el patrón. Con este pequeño cambio, la expresión regular ahora combina 1-a-4 o 1 a 4 pero no 1 a-4 o 1-a/4 .

El número a usar para su referencia de respaldo depende de la ubicación de su grupo de captura. El número puede ser de uno a nueve y se puede encontrar contando sus grupos de captura.

([0-9])([-/ ])[a-z][-/ ]([0-9])
|--1--||--2--|          |--3--|

Los grupos de captura anidados cambian este conteo ligeramente. Primero cuenta el grupo de captura exterior, luego el siguiente nivel y continúa hasta que abandonas el nido:

(([0-9])([-/ ]))([a-z])
 |--2--||--3--|
|-------1------||--4--|

Referencias ambiguas

Problema: necesita hacer coincidir el texto de un determinado formato, por ejemplo:

1-a-0
6/p/0
4 g 0

Eso es un dígito, un separador (uno de - , / , o un espacio), una letra, el mismo separador y un cero.

Solución ingenua: adaptando la expresión regular del ejemplo de Conceptos básicos , puede encontrar esta expresión regular:

[0-9]([-/ ])[a-z]\10

Pero eso probablemente no funcionará. La mayoría de los tipos de expresiones regulares admiten más de nueve grupos de captura, y muy pocos de ellos son lo suficientemente inteligentes como para darse cuenta de que, dado que solo hay un grupo de captura, \10 debe ser una referencia inversa al grupo 1 seguido de un 0 literal. La mayoría de los sabores lo tratarán como una referencia inversa al grupo 10. Algunos de ellos lanzarán una excepción porque no hay un grupo 10; el resto simplemente no coincidirá.

Hay varias formas de evitar este problema. Una es usar grupos con nombre (y referencias con nombre):

[0-9](?<sep>[-/ ])[a-z]\k<sep>0

Si su lenguaje de expresiones regulares lo admite, el formato \g{n} (donde n es un número) puede incluir el número de referencia inversa entre paréntesis para separarlo de cualquier dígito después de él:

[0-9]([-/ ])[a-z]\g{1}0

Otra forma es usar el formato de expresiones regulares extendido, separando los elementos con espacios en blanco insignificantes (en Java, tendrá que escapar del espacio entre paréntesis):

(?x) [0-9] ([-/ ]) [a-z] \1 0

Si su versión de expresiones regulares no es compatible con esas características, puede agregar una sintaxis innecesaria pero inofensiva, como un grupo que no captura:

[0-9]([-/ ])[a-z](?:\1)0

... o un cuantificador ficticio (esta es posiblemente la única circunstancia en la que {1} es útil):

[0-9]([-/ ])[a-z]\1{1}0


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow