PHP 8.5.0 Beta 2 available for testing

Subpatrones condicionales

Es posible hacer que el proceso de coincidencia obedezca un subpatrón condicionalmente o elegir entre dos subpatrones alternativos, dependiendo del resultado de una afirmación, o si un subpatrón de captura anterior coincidió o no. Las dos formas posibles de subpatrón condicional son

(?(condition)yes-pattern)
(?(condition)yes-pattern|no-pattern)

Si la condición se cumple, se usa el yes-pattern; de lo contrario se usa el no-pattern (si está presente). Si hay más de dos alternativas en el subpatrón, ocurre un error en el momento de la compilación.

Hay dos tipos de condiciones. Si el texto entre los paréntesis consiste en una secuencia de dígitos, entonces la condición se cumple si el subpatrón de captura de ese número ha coincidido anteriormente. Considere el siguiente patrón, que contiene espacio en blanco no significativo para hacerlo más legible (asumiendo la opción PCRE_EXTENDED y para dividirlo en tres partes para facilitar la discusión):

( \( )? [^()]+ (?(1) \) )

La primera parte coincide con un paréntesis de apertura opcional, y si ese carácter está presente, lo establece como la primera subcadena capturada. La segunda parte coincide con uno o más caracteres que no son paréntesis. La tercera parte es un subpatrón condicional que prueba si el primer conjunto de paréntesis coincidió o no. Si lo hicieron, es decir, si el sujeto comenzó con un paréntesis de apertura, la condición es true, y por lo tanto el yes-pattern se ejecuta y se requiere un paréntesis de cierre. De lo contrario, ya que no-pattern no está presente, el subpatrón coincide con nada. En otras palabras, este patrón coincide con una secuencia de caracteres no paréntesis, opcionalmente encerrada en paréntesis.

Si la condición es la cadena (R), se cumple si se ha realizado una llamada recursiva al patrón o subpatrón. En "nivel superior", la condición es falsa.

Si la condición no es una secuencia de dígitos o (R), debe ser una afirmación. Esta puede ser una afirmación positiva o negativa de anticipación o retroceso. Considere este patrón, que nuevamente contiene espacio en blanco no significativo, y con las dos alternativas en la segunda línea:

(?(?=[^a-z]*[a-z])
\d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )

La condición es una afirmación positiva de anticipación que coincide con una secuencia opcional de caracteres no letras seguida de una letra. En otras palabras, prueba la presencia de al menos una letra en el sujeto. Si se encuentra una letra, el sujeto se compara con la primera alternativa; de lo contrario, se compara con la segunda. Este patrón coincide con cadenas en una de las dos formas dd-aaa-dd o dd-dd-dd, donde aaa son letras y dd son dígitos.

add a note

User Contributed Notes 1 note

up
5
Anonymous
14 years ago
Repetition of a subpattern will repeat conditionals that are contained inside it, updating subpattern matches with iteration.

Consider the following code, which scans thru HTML, keeping track of angle brackets "<" ">". If open bracket "<" matches, then closing bracket ">" must follow before repetition can possibly end. That way regex will effectively match only outside of tags.

<?php
$pattern
='%(*ANY)(.*?(<)(?(2).*?>)(.*?))*?\'\'%s';
$replace='\1Fred';
$subject=
'<html><body class=\'\'>\'\' went to '\'\meyer and ran
into <b>\'\'</b>.
</body></html>'
echo preg_replace("%(*ANY)(.*?((<)(?(3).*?>).*?)*?)\'\'%s",'\1Fred',$subject);
?>

Output will be:
'<html><body class=\'\'>Fred went to Fredmeyer and ran
into <b>Fred</b>.
</body></html>'
To Top