Retroreferencias
Fuera de una clase carácter, una barra invertida seguida por un dígito
mayor que 0 (y posiblemente más dígitos) es una retroreferencia
a un sub-patrón de captura anterior (esto es a su izquierda)
del patrón, siempre que hayan habido tantas capturas entre
paréntesis previas a la izquierda.
Sin embargo, si el número decimal que sigue a la barra invertida es
menor que 10, siempre es tomado como una retroreferencia, y
produce un error sólo si no hay tantas capturas
anteriores entre paréntesis en el patrón completo. En otras palabras, los
paréntesis que son referenciados no necesitan estar a la izquierda de
la referencia para números menores que 10.
Una "retroreferencia hacia adelante" puede tener sentido cuando está involucrada
una repetición y el sub-patrón de la derecha ha participado
en una iteración anterior. Véase la sección anterior
titulada "Barra invertida" para más detalles acerca del manejo de
los dígitos que siguen a una barra invertida.
Una retroreferencia coincide con cualquier cosa que en realidad haya coincidido
con el sub-patrón de captura en la cadena objetivo actual, más que con
cualquier cosa que coincida en el sub-patrón mismo. Así, el patrón
(abraz|apreci)o de un \1ador
coindice con "abrazo de un abrazador" y con "aprecio de un apreciador",
pero no con "abrazo de un apreciador". Si la coincidencia sensible a
mayúsculas-minúsculas está en vigor en el momento de la retroreferencia,
la distinción de letras es relevante. Por ejemplo,
((?i)bla)\s+\1
coincide con "bla bla" y "BLA BLA", pero no con "BLA bla", incluso
si el patrón de captura original es comparado de forma insensible a
mayúsculas-minúsculas.
Puede haber más de una retroreferencia hacia el mismo sub-patrón.
Si un sub-patrón no ha sido usado en realidad en una
coincidencia en particular, cualquier retroreferencia a él siempre
falla. Por ejemplo, el patrón
(a|(bc))\2
siempre falla si comienza coincidiendo con "a" en vez de con "bc".
Ya que puede haber hasta 99 retroreferencias, todos los dígitos
que siguen a la barra invertida se toman como parte de un número
posible de retroreferencias. Si el patrón continúa con un carácter
dígito, entonces se deben usar algunos delimitadores para finalizar la
retroreferencia. Si la opción PCRE_EXTENDED está
establecida, éste puede ser un espacio en blanco. De otra manera se puede usar un comentario vacío.
Una retroreferencia que sucede dentro de los paréntesis a los cuales
se refiere, falla cuando el sub-patrón se usa primero, así, por
ejemplo, (a\1) nunca coincide. Sin embargo, tales referencias pueden
ser útiles dentro de sub-patrones repetidos. Por ejemplo, el patrón
(a|b\1)+
coincide con cualquier número de "a"es y tambíen con "aba", "ababba", etc. En
cada iteración del subpatrón, la retroreferencia coincide con
el cadena correspondiente a la iteración anterior.
Para que esto funcione, el patrón debe ser tal
que la primera iteración no necesite coincidir con la retroreferencia.
Esto se puede lograr usando alternancia, como en el
ejemplo anterior, o mediante un cuantificador con un mínimo de cero.
A partir de PHP 5.2.2, la secuencia de escape \g
se puede
usar para referenciar subpatrones de forma absoluta y relativa.
Esta secuencia de escape debe estar seguida por un número sin signo o un número
negativo, opcionalmente encerrado entre llaves. Las secuencias \1
,
\g1
y \g{1}
son sinónimas
unas de otras. El uso de este patrón con un número sin signo puede
ayudar a eliminar la ambigüedad inherente al usar dígitos seguidos de una
barra invertida. La secuencia ayuda a distinguir retroreferencias de caracteres
octales y también hace más fácil tener una retroreferencia seguida
por un número literal, p.ej. \g{2}1
.
El uso de la secuencia \g
con un número negativo
significa una referencia relativa. Por ejemplo, (foo)(bar)\g{-1}
coincidiría con la secuencia "foobarbar" y (foo)(bar)\g{-2}
coincidiría con "foobarfoo". Esto puede ser útil en patrones largos como una alternativa
de seguir la pista del número de subpatrones para referenciar
un subpatrón previo específico.
Las retroreferencias a sub-patrones nominados se pueden lograr mediante
(?P=nombre)
o, desde PHP 5.2.2, también mediante
\k<nombre>
o \k'nombre'
.
Además, PHP 5.2.4 añadió soporte para \k{nombre}
y \g{nombre}
, y PHP 5.2.7 para
\g<name>
y \g'name'
.