1
0
mirror of https://github.com/php/doc-es.git synced 2026-03-23 23:12:09 +01:00
Files
archived-doc-es/reference/pcre/pattern.syntax.xml
2025-08-29 12:39:32 +02:00

2135 lines
96 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: a0434e05111acabf2b9b2c7847e7e733f8dab0dc Maintainer: PhilDaiguille Status: ready -->
<!-- Reviewed: no -->
<!-- splitted from ./en/functions/pcre.xml, last change in rev 1.2 -->
<chapter xml:id="reference.pcre.pattern.syntax" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Sintaxis de patrones</title>
<titleabbrev>Sintaxis de expresiones regulares PCRE</titleabbrev>
<section xml:id="regexp.introduction">
<title>Introducción</title>
<para>
La sintaxis y semántica de las expresiones regulares
soportadas por PCRE se describen en esta sección. Las expresiones regulares también se
describen en la documentación de Perl y en varios
otros libros, algunos de los cuales tienen ejemplos abundantes. El libro
"Mastering Regular Expressions" de Jeffrey
Friedl, publicado por O'Reilly (ISBN 1-56592-257-3), las cubre en gran detalle.
La descripción aquí está destinada como documentación de referencia.
</para>
<para>
Una expresión regular es un patrón que se compara con una
cadena de sujeto de izquierda a derecha. La mayoría de los caracteres representan
a sí mismos en un patrón, y coinciden con los
caracteres correspondientes en el sujeto. Como ejemplo trivial, el patrón
<literal>The quick brown fox</literal>
coincide con una parte de una cadena de sujeto que es idéntica
a sí misma.
</para>
</section>
<section xml:id="regexp.reference.delimiters">
<title>Delimitadores</title>
<para>
Al usar las funciones PCRE, es obligatorio que el patrón esté encerrado
por <emphasis>delimitadores</emphasis>. Un delimitador puede ser cualquier carácter no alfanumérico,
no barra invertida, no espacio en blanco.
Los espacios en blanco iniciales antes de un delimitador válido se ignoran silenciosamente.
</para>
<para>
Los delimitadores comúnmente utilizados son las barras inclinadas hacia adelante (<literal>/</literal>), signos de número
(<literal>#</literal>) y tildes (<literal>~</literal>). Los siguientes son ejemplos de patrones delimitados válidos.
<informalexample>
<programlisting>
<![CDATA[
/foo bar/
#^[^0-9]$#
+php+
%[a-zA-Z0-9_-]%
]]>
</programlisting>
</informalexample>
</para>
<para>
También es posible usar
delimitadores de estilo de corchetes donde los corchetes de apertura y cierre son el delimitador de inicio y fin, respectivamente. <literal>()</literal>,
<literal>{}</literal>, <literal>[]</literal> y <literal>&lt;&gt;</literal>
son todos pares de delimitadores de estilo de corchetes válidos.
<informalexample>
<programlisting>
<![CDATA[
(this [is] a (pattern))
{this [is] a (pattern)}
[this [is] a (pattern)]
<this [is] a (pattern)>
]]>
</programlisting>
</informalexample>
Los delimitadores de estilo de corchetes no necesitan ser escapados cuando se usan como metacaracteres dentro del patrón, pero como con otros delimitadores deben ser escapados cuando se usan como caracteres literales.
</para>
<para>
Si el delimitador necesita coincidir dentro del patrón debe ser
escapado usando una barra invertida. Si el delimitador aparece con frecuencia dentro del
patrón, es una buena idea elegir otro delimitador para aumentar
la legibilidad.
<informalexample>
<programlisting>
<![CDATA[
/http:\/\//
#http://#
]]>
</programlisting>
</informalexample>
La función <function>preg_quote</function> puede ser utilizada para escapar una cadena
para inyectarla en un patrón y su segundo parámetro opcional puede ser utilizado
para especificar el delimitador a escapar.
</para>
<para>
Puede agregar <link linkend="reference.pcre.pattern.modifiers">modificadores de patrón</link> después del delimitador final. El siguiente es un ejemplo
de coincidencia sin distinción de mayúsculas y minúsculas:
<informalexample>
<programlisting>
<![CDATA[
#[a-z]#i
]]>
</programlisting>
</informalexample>
</para>
</section>
<section xml:id="regexp.reference.meta">
<title>Metacaracteres</title>
<para>
El poder de las expresiones regulares proviene de la
capacidad de incluir alternativas y repeticiones en el
patrón. Estas se codifican en el patrón mediante el uso de
<emphasis>metacaracteres</emphasis>, que no se representan a sí mismos, sino que se interpretan de alguna manera especial.
</para>
<para>
Hay dos conjuntos diferentes de metacaracteres: aquellos que
se reconocen en cualquier parte del patrón excepto dentro de corchetes, y aquellos que se reconocen dentro de corchetes.
Fuera de corchetes, los metacaracteres son los siguientes:
<table>
<title>Metacaracteres fuera de corchetes</title>
<tgroup cols="2">
<thead>
<row>
<entry>Metacaracter</entry><entry>Descripción</entry>
</row>
</thead>
<tbody>
<row>
<entry>\</entry><entry>carácter de escape general con varios usos</entry>
</row>
<row>
<entry>^</entry><entry>asegurar el inicio del sujeto (o línea, en modo multiline)</entry>
</row>
<row>
<entry>$</entry><entry>asegurar el final del sujeto o antes de un salto de línea de terminación (o final de línea, en modo multiline)</entry>
</row>
<row>
<entry>.</entry><entry>coincidir con cualquier carácter excepto salto de línea (por defecto)</entry>
</row>
<row>
<entry>[</entry><entry>inicio de definición de clase de caracteres</entry>
</row>
<row>
<entry>]</entry><entry>fin de definición de clase de caracteres</entry>
</row>
<row>
<entry>|</entry><entry>inicio de rama alternativa</entry>
</row>
<row>
<entry>(</entry><entry>inicio de subpatrón</entry>
</row>
<row>
<entry>)</entry><entry>fin de subpatrón</entry>
</row>
<row>
<entry>?</entry><entry>extiende el significado de (, también 0 o 1 cuantificador, también hace que los cuantificadores codiciosos sean perezosos (ver <link linkend="regexp.reference.repetition">repetición</link>)</entry>
</row>
<row>
<entry>*</entry><entry>cuantificador 0 o más</entry>
</row>
<row>
<entry>+</entry><entry>cuantificador 1 o más</entry>
</row>
<row>
<entry>{</entry><entry>inicio de cuantificador min/max</entry>
</row>
<row>
<entry>}</entry><entry>fin de cuantificador min/max</entry>
</row>
</tbody>
</tgroup>
</table>
Una parte de un patrón que está dentro de corchetes se llama
<link linkend="regexp.reference.character-classes">clase de caracteres</link>. En una clase de caracteres los únicos
metacaracteres son:
<table>
<title>Metacaracteres dentro de corchetes (<emphasis>clases de caracteres</emphasis>)</title>
<tgroup cols="2">
<thead>
<row>
<entry>Metacaracter</entry><entry>Descripción</entry>
</row>
</thead>
<tbody>
<row>
<entry>\</entry><entry>carácter de escape general</entry>
</row>
<row>
<entry>^</entry><entry>niega la clase, pero solo si es el primer carácter</entry>
</row>
<row>
<entry>-</entry><entry>indica rango de caracteres</entry>
</row>
</tbody>
</tgroup>
</table>
Las siguientes secciones describen el uso de cada uno de los
metacaracteres.
</para>
</section>
<section xml:id="regexp.reference.escape">
<title>Secuencias de escape</title>
<para>
El carácter de barra invertida tiene varios usos. En primer lugar, si está
seguido por un carácter no alfanumérico, elimina cualquier
significado especial que el carácter pueda tener. Este uso de
barra invertida como carácter de escape se aplica tanto dentro como fuera de clases de caracteres.
</para>
<para>
Por ejemplo, si desea coincidir con un carácter "*", escribe
"\*" en el patrón. Esto se aplica ya sea que el
carácter siguiente sería interpretado de otra manera como un
metacarácter, por lo que siempre es seguro preceder un no alfanumérico
con "\" para especificar que representa a sí mismo. En
particular, si desea coincidir con una barra invertida, escribe "\\".
</para>
<note>
<para>
Las cadenas de PHP con comillas simples y dobles <link
linkend="language.types.string.syntax">tienen</link> un significado especial de barra invertida. Por lo tanto, si \ debe coincidir con una expresión regular \\, entonces "\\\\" o '\\\\' debe usarse en el código PHP.
</para>
</note>
<para>
Si un patrón se compila con la
<link linkend="reference.pcre.pattern.modifiers">opción PCRE_EXTENDED</link>,
el espacio en blanco en el patrón (excepto en una clase de caracteres) y
los caracteres entre un "#" fuera de una clase de caracteres y el siguiente carácter de nueva línea
se ignoran. Una barra invertida de escape puede usarse para incluir un
carácter de espacio en blanco o "#" como parte del patrón.
</para>
<para>
Un segundo uso de la barra invertida proporciona una manera de codificar
caracteres no imprimibles en patrones de manera visible. No hay restricción sobre la aparición de caracteres no imprimibles,
aparte del cero binario que termina un patrón,
pero cuando un patrón se está preparando mediante edición de texto, generalmente es
más fácil usar una de las siguientes secuencias de escape
que el carácter binario que representan:
</para>
<para>
<variablelist>
<varlistentry>
<term><emphasis>\a</emphasis></term>
<listitem>
<simpara>alarma, es decir, el carácter BEL (hex 07)</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\cx</emphasis></term>
<listitem>
<simpara>"control-x", donde x es cualquier carácter</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\e</emphasis></term>
<listitem>
<simpara>escape (hex 1B)</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\f</emphasis></term>
<listitem>
<simpara>salto de página (hex 0C)</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\n</emphasis></term>
<listitem>
<simpara>nueva línea (hex 0A)</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\p{xx}</emphasis></term>
<listitem>
<simpara>
un carácter con la propiedad xx, ver
<link linkend="regexp.reference.unicode">propiedades unicode</link>
para más información
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\P{xx}</emphasis></term>
<listitem>
<simpara>
un carácter sin la propiedad xx, ver
<link linkend="regexp.reference.unicode">propiedades unicode</link>
para más información
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\r</emphasis></term>
<listitem>
<simpara>retorno de carro (hex 0D)</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\R</emphasis></term>
<listitem>
<simpara>salto de línea: coincide con \n, \r y \r\n</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\t</emphasis></term>
<listitem>
<simpara>tabulador (hex 09)</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\xhh</emphasis></term>
<listitem>
<simpara>
carácter con código hex hh
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\ddd</emphasis></term>
<listitem>
<simpara>carácter con código octal ddd, o referencia inversa</simpara>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
El efecto preciso de "<literal>\cx</literal>" es el siguiente:
si "<literal>x</literal>" es una letra minúscula, se convierte
a mayúscula. Luego se invierte el bit 6 del carácter (hex 40).
Así, "<literal>\cz</literal>" se convierte en hex 1A, pero
"<literal>\c{</literal>" se convierte en hex 3B, mientras que "<literal>\c;</literal>"
se convierte en hex 7B.
</para>
<para>
Después de "<literal>\x</literal>", se leen hasta dos dígitos hexadecimales (las letras pueden estar en mayúsculas o minúsculas).
En <emphasis>modo UTF-8</emphasis>, "<literal>\x{...}</literal>" está permitido, donde el contenido de las llaves es una cadena de dígitos hexadecimales. Se interpreta como un carácter UTF-8 cuyo número de código es el número hexadecimal dado. La secuencia de escape hexadecimal original,
<literal>\xhh</literal>, coincide con un carácter UTF-8 de dos bytes si el valor es mayor que 127.
</para>
<para>
Después de "<literal>\0</literal>" se leen hasta dos dígitos octales adicionales.
En ambos casos, si hay menos de dos dígitos, solo se usan los que
están presentes. Así, la secuencia "<literal>\0\x\07</literal>"
especifica dos ceros binarios seguidos de un carácter BEL. Asegúrese de
proporcionar dos dígitos después del cero inicial si el carácter
que sigue es él mismo un dígito octal.
</para>
<para>
El manejo de una barra invertida seguida de un dígito que no sea 0
es complicado. Fuera de una clase de caracteres, PCRE lo lee
y cualquier dígito siguiente como un número decimal. Si el número
es menor que 10, o si ha habido al menos esa cantidad de
paréntesis de apertura de captura anteriores en la expresión, la
secuencia completa se toma como una <emphasis>referencia inversa</emphasis>. Una descripción
de cómo funciona esto se da más adelante, después de la discusión
de subpatrones entre paréntesis.
</para>
<para>
Dentro de una clase de caracteres, o si el número decimal es
mayor que 9 y no ha habido tantas subpatrones de captura, PCRE vuelve a leer
hasta tres dígitos octales siguientes
a la barra invertida, y genera un solo byte a partir de
los 8 bits menos significativos del valor. Los dígitos posteriores se representan a sí mismos. Por ejemplo:
</para>
<para>
<variablelist>
<varlistentry>
<term><emphasis>\040</emphasis></term>
<listitem><simpara>es otra forma de escribir un espacio</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\40</emphasis></term>
<listitem>
<simpara>
es lo mismo, siempre que haya menos de 40
subpatrones de captura anteriores
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\7</emphasis></term>
<listitem><simpara>siempre es una referencia inversa</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\11</emphasis></term>
<listitem>
<simpara>
podría ser una referencia inversa, o otra forma de
escribir un tabulador
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\011</emphasis></term>
<listitem><simpara>siempre es un tabulador</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\0113</emphasis></term>
<listitem><simpara>es un tabulador seguido del carácter "3"</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\113</emphasis></term>
<listitem>
<simpara>
es el carácter con código octal 113 (ya que no puede haber más de 99 referencias inversas)
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\377</emphasis></term>
<listitem><simpara>es un byte compuesto completamente de 1 bits</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\81</emphasis></term>
<listitem>
<simpara>
es una referencia inversa, o un cero binario
seguido de los dos caracteres "8" y "1"
</simpara>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Tenga en cuenta que los valores octales de 100 o más no deben introducirse con un cero inicial, ya que nunca se leen más de tres dígitos octales.
</para>
<para>
Todas las secuencias que definen un valor de un solo byte pueden usarse tanto dentro como fuera de clases de caracteres. Además,
dentro de una clase de caracteres, la secuencia "<literal>\b</literal>"
se interpreta como el carácter de retroceso (hex 08). Fuera de una clase de caracteres tiene un significado diferente (ver más abajo).
</para>
<para>
El tercer uso de la barra invertida es para especificar tipos de caracteres genéricos:
</para>
<para>
<variablelist>
<varlistentry>
<term><emphasis>\d</emphasis></term>
<listitem><simpara>cualquier dígito decimal</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\D</emphasis></term>
<listitem><simpara>cualquier carácter que no sea un dígito decimal</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\h</emphasis></term>
<listitem><simpara>cualquier carácter de espacio en blanco horizontal</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\H</emphasis></term>
<listitem><simpara>cualquier carácter que no sea un carácter de espacio en blanco horizontal</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\s</emphasis></term>
<listitem><simpara>cualquier carácter de espacio en blanco</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\S</emphasis></term>
<listitem><simpara>cualquier carácter que no sea un carácter de espacio en blanco</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\v</emphasis></term>
<listitem><simpara>cualquier carácter de espacio en blanco vertical</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\V</emphasis></term>
<listitem><simpara>cualquier carácter que no sea un carácter de espacio en blanco vertical</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\w</emphasis></term>
<listitem><simpara>cualquier carácter de "palabra"</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\W</emphasis></term>
<listitem><simpara>cualquier carácter "no palabra"</simpara></listitem>
</varlistentry>
</variablelist>
</para>
<para>
Cada par de secuencias de escape divide el conjunto completo de
caracteres en dos conjuntos disjuntos. Cualquier carácter
dado coincide con uno, y solo uno, de cada par.
</para>
<para>
Los caracteres de "espacio en blanco" son HT (9), LF (10), FF (12), CR (13),
y espacio (32). Sin embargo, si se está realizando una coincidencia específica de la configuración regional,
los caracteres con puntos de código en el rango 128-255 también pueden considerarse
como caracteres de espacio en blanco, por ejemplo, NBSP (A0).
</para>
<para>
Un carácter de "palabra" es cualquier letra o dígito o el carácter de subrayado,
es decir, cualquier carácter que pueda ser parte de
una "palabra" de Perl. La definición de letras y dígitos está
controlada por las tablas de caracteres de PCRE, y puede variar si se está realizando una coincidencia específica de la configuración regional. Por ejemplo, en la configuración regional "fr" (francés), algunos códigos de caracteres mayores que 128 se usan para letras acentuadas,
y estas coinciden con <literal>\w</literal>.
</para>
<para>
Estas secuencias de tipos de caracteres pueden aparecer tanto dentro como
fuera de clases de caracteres. Cada una coincide con un carácter de
tipo apropiado. Si el punto de coincidencia actual está al final
de la cadena de sujeto, todas fallan, ya que no hay carácter para coincidir.
</para>
<para>
El cuarto uso de la barra invertida es para ciertas afirmaciones simples.
Una afirmación especifica una condición que debe cumplirse
en un punto particular en una coincidencia, sin consumir ningún
carácter de la cadena de sujeto. El uso de subpatrones
para afirmaciones más complicadas se describe a continuación. Las
afirmaciones con barra invertida son
</para>
<para>
<variablelist>
<varlistentry>
<term><emphasis>\b</emphasis></term>
<listitem><simpara>límite de palabra</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\B</emphasis></term>
<listitem><simpara>no es un límite de palabra</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\A</emphasis></term>
<listitem><simpara>inicio del sujeto (independiente del modo multiline)</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\Z</emphasis></term>
<listitem>
<simpara>
final del sujeto o salto de línea al final (independiente del
modo multiline)
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\z</emphasis></term>
<listitem><simpara>final del sujeto (independiente del modo multiline)</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\G</emphasis></term>
<listitem><simpara>primera posición de coincidencia en el sujeto</simpara></listitem>
</varlistentry>
</variablelist>
</para>
<para>
Estas afirmaciones no pueden aparecer en clases de caracteres (pero
note que "<literal>\b</literal>" tiene un significado diferente, a saber, el carácter de retroceso, dentro de una clase de caracteres).
</para>
<para>
Un límite de palabra es una posición en la cadena de sujeto donde
el carácter actual y el carácter anterior no coinciden ambos
con <literal>\w</literal> o <literal>\W</literal> (es decir, uno coincide
con <literal>\w</literal> y el otro coincide
con <literal>\W</literal>), o el inicio o final de la cadena si el primer
o último carácter coincide con <literal>\w</literal>, respectivamente.
</para>
<para>
Las afirmaciones <literal>\A</literal>, <literal>\Z</literal> y
<literal>\z</literal> difieren de las afirmaciones tradicionales
de circunflejo y dólar (descritas en <link linkend="regexp.reference.anchors">anclajes</link> )
en que solo coinciden en el inicio y final exactos de la cadena de sujeto,
independientemente de las opciones establecidas. No se ven afectadas por las
opciones <link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link> o
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOLLAR_ENDONLY</link>.
La diferencia entre <literal>\Z</literal> y
<literal>\z</literal> es que <literal>\Z</literal> coincide antes de un salto de línea que es el último carácter de la cadena así como al final de
la cadena, mientras que <literal>\z</literal> solo coincide al final.
</para>
<para>
La afirmación <literal>\G</literal> es verdadera solo cuando la posición de coincidencia actual está en el punto de inicio de la coincidencia, como se especifica por
el argumento <parameter>offset</parameter> de
<function>preg_match</function>. Difiere de <literal>\A</literal>
cuando el valor de <parameter>offset</parameter> no es cero.
</para>
<para>
<literal>\Q</literal> y <literal>\E</literal> pueden usarse para ignorar
metacaracteres de regexp en el patrón. Por ejemplo:
<literal>\w+\Q.$.\E$</literal> coincidirá con uno o más caracteres de palabra,
seguido de literales <literal>.$.</literal> y anclado al final
de la cadena. Tenga en cuenta que esto no cambia el comportamiento de
los delimitadores; por ejemplo, el patrón <literal>#\Q#\E#$</literal>
no es válido, porque el segundo <literal>#</literal> marca el final del patrón, y el <literal>\E#</literal> se interpreta como modificadores inválidos.
</para>
<para>
<literal>\K</literal> puede usarse para restablecer el inicio de la coincidencia.
Por ejemplo, el patrón <literal>foo\Kbar</literal> coincide
con "foobar", pero informa que ha coincidido con "bar". El uso de
<literal>\K</literal> no interfiere con la configuración de subcadenas capturadas. Por ejemplo, cuando el patrón <literal>(foo)\Kbar</literal>
coincide con "foobar", la primera subcadena sigue configurada en "foo".
</para>
</section>
<section xml:id="regexp.reference.unicode">
<title>Propiedades de caracteres Unicode</title>
<para>
Desde 5.1.0, tres
secuencias de escape adicionales para coincidir con tipos de caracteres genéricos están disponibles
cuando se selecciona el <emphasis>modo UTF-8</emphasis>. Son:
</para>
<variablelist>
<varlistentry>
<term><emphasis>\p{xx}</emphasis></term>
<listitem><simpara>un carácter con la propiedad xx</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\P{xx}</emphasis></term>
<listitem><simpara>un carácter sin la propiedad xx</simpara></listitem>
</varlistentry>
<varlistentry>
<term><emphasis>\X</emphasis></term>
<listitem><simpara>una secuencia Unicode extendida</simpara></listitem>
</varlistentry>
</variablelist>
<para>
Los nombres de propiedades representados por <literal>xx</literal> arriba están limitados
a las propiedades generales de categoría Unicode. Cada carácter tiene exactamente una
de estas propiedades, especificada por una abreviatura de dos letras. Para compatibilidad con
Perl, la negación puede especificarse incluyendo una circunflejo entre la llave de apertura y el nombre de la propiedad. Por ejemplo, <literal>\p{^Lu}</literal>
es lo mismo que <literal>\P{Lu}</literal>.
</para>
<para>
Si solo se especifica una letra con <literal>\p</literal> o
<literal>\P</literal>, incluye todas las propiedades que comienzan con esa
letra. En este caso, en ausencia de negación, las llaves en la
secuencia de escape son opcionales; estos dos ejemplos tienen el mismo efecto:
</para>
<informalexample>
<programlisting>
<![CDATA[
\p{L}
\pL
]]>
</programlisting>
</informalexample>
<table>
<title>Códigos de propiedades admitidos</title>
<tgroup cols="3">
<thead>
<row>
<entry>Propiedad</entry>
<entry>Coincide con</entry>
<entry>Notas</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>C</literal></entry>
<entry>Otro</entry>
<entry></entry>
</row>
<row>
<entry><literal>Cc</literal></entry>
<entry>Control</entry>
<entry></entry>
</row>
<row>
<entry><literal>Cf</literal></entry>
<entry>Formato</entry>
<entry></entry>
</row>
<row>
<entry><literal>Cn</literal></entry>
<entry>No asignado</entry>
<entry></entry>
</row>
<row>
<entry><literal>Co</literal></entry>
<entry>Uso privado</entry>
<entry></entry>
</row>
<row rowsep="1">
<entry><literal>Cs</literal></entry>
<entry>Sustituto</entry>
<entry></entry>
</row>
<row>
<entry><literal>L</literal></entry>
<entry>Letra</entry>
<entry>
Incluye las siguientes propiedades: <literal>Ll</literal>,
<literal>Lm</literal>, <literal>Lo</literal>, <literal>Lt</literal> y
<literal>Lu</literal>.
</entry>
</row>
<row>
<entry><literal>Ll</literal></entry>
<entry>Letra minúscula</entry>
<entry></entry>
</row>
<row>
<entry><literal>Lm</literal></entry>
<entry>Letra modificadora</entry>
<entry></entry>
</row>
<row>
<entry><literal>Lo</literal></entry>
<entry>Otra letra</entry>
<entry></entry>
</row>
<row>
<entry><literal>Lt</literal></entry>
<entry>Letra con mayúscula inicial</entry>
<entry></entry>
</row>
<row rowsep="1">
<entry><literal>Lu</literal></entry>
<entry>Letra mayúscula</entry>
<entry></entry>
</row>
<row>
<entry><literal>M</literal></entry>
<entry>Marca</entry>
<entry></entry>
</row>
<row>
<entry><literal>Mc</literal></entry>
<entry>Marca de espacio</entry>
<entry></entry>
</row>
<row>
<entry><literal>Me</literal></entry>
<entry>Marca de cierre</entry>
<entry></entry>
</row>
<row rowsep="1">
<entry><literal>Mn</literal></entry>
<entry>Marca no espaciada</entry>
<entry></entry>
</row>
<row>
<entry><literal>N</literal></entry>
<entry>Número</entry>
<entry></entry>
</row>
<row>
<entry><literal>Nd</literal></entry>
<entry>Número decimal</entry>
<entry></entry>
</row>
<row>
<entry><literal>Nl</literal></entry>
<entry>Número de letra</entry>
<entry></entry>
</row>
<row rowsep="1">
<entry><literal>No</literal></entry>
<entry>Otro número</entry>
<entry></entry>
</row>
<row>
<entry><literal>P</literal></entry>
<entry>Puntuación</entry>
<entry></entry>
</row>
<row>
<entry><literal>Pc</literal></entry>
<entry>Puntuación de conexión</entry>
<entry></entry>
</row>
<row>
<entry><literal>Pd</literal></entry>
<entry>Puntuación de guión</entry>
<entry></entry>
</row>
<row>
<entry><literal>Pe</literal></entry>
<entry>Puntuación de cierre</entry>
<entry></entry>
</row>
<row>
<entry><literal>Pf</literal></entry>
<entry>Puntuación final</entry>
<entry></entry>
</row>
<row>
<entry><literal>Pi</literal></entry>
<entry>Puntuación inicial</entry>
<entry></entry>
</row>
<row>
<entry><literal>Po</literal></entry>
<entry>Otra puntuación</entry>
<entry></entry>
</row>
<row rowsep="1">
<entry><literal>Ps</literal></entry>
<entry>Puntuación de apertura</entry>
<entry></entry>
</row>
<row>
<entry><literal>S</literal></entry>
<entry>Símbolo</entry>
<entry></entry>
</row>
<row>
<entry><literal>Sc</literal></entry>
<entry>Símbolo de moneda</entry>
<entry></entry>
</row>
<row>
<entry><literal>Sk</literal></entry>
<entry>Símbolo modificador</entry>
<entry></entry>
</row>
<row>
<entry><literal>Sm</literal></entry>
<entry>Símbolo matemático</entry>
<entry></entry>
</row>
<row rowsep="1">
<entry><literal>So</literal></entry>
<entry>Otro símbolo</entry>
<entry>Incluye emojis</entry>
</row>
<row>
<entry><literal>Z</literal></entry>
<entry>Separador</entry>
<entry></entry>
</row>
<row>
<entry><literal>Zl</literal></entry>
<entry>Separador de línea</entry>
<entry></entry>
</row>
<row>
<entry><literal>Zp</literal></entry>
<entry>Separador de párrafo</entry>
<entry></entry>
</row>
<row>
<entry><literal>Zs</literal></entry>
<entry>Separador de espacio</entry>
<entry></entry>
</row>
</tbody>
</tgroup>
</table>
<para>
Las propiedades extendidas como <literal>InMusicalSymbols</literal> no
son soportadas por PCRE.
</para>
<para>
Especificar coincidencia sin distinción de mayúsculas y minúsculas no afecta estas secuencias de escape.
Por ejemplo, <literal>\p{Lu}</literal> siempre coincide solo con letras mayúsculas.
</para>
<para>
Los conjuntos de caracteres Unicode están definidos como pertenecientes a ciertos guiones. Un
carácter de uno de estos conjuntos puede coincidir usando un nombre de guión. Por
ejemplo:
</para>
<itemizedlist>
<listitem>
<simpara><literal>\p{Greek}</literal></simpara>
</listitem>
<listitem>
<simpara><literal>\P{Han}</literal></simpara>
</listitem>
</itemizedlist>
<para>
Aquellos que no son parte de un guión identificado se agrupan juntos como
<literal>Common</literal>. La lista actual de guiones es:
</para>
<table>
<title>Guiones admitidos</title>
<tgroup cols="5">
<tbody>
<row>
<entry><literal>Arabic</literal></entry>
<entry><literal>Armenian</literal></entry>
<entry><literal>Avestan</literal></entry>
<entry><literal>Balinese</literal></entry>
<entry><literal>Bamum</literal></entry>
</row>
<row>
<entry><literal>Batak</literal></entry>
<entry><literal>Bengali</literal></entry>
<entry><literal>Bopomofo</literal></entry>
<entry><literal>Brahmi</literal></entry>
<entry><literal>Braille</literal></entry>
</row>
<row>
<entry><literal>Buginese</literal></entry>
<entry><literal>Buhid</literal></entry>
<entry><literal>Canadian_Aboriginal</literal></entry>
<entry><literal>Carian</literal></entry>
<entry><literal>Chakma</literal></entry>
</row>
<row>
<entry><literal>Cham</literal></entry>
<entry><literal>Cherokee</literal></entry>
<entry><literal>Common</literal></entry>
<entry><literal>Coptic</literal></entry>
<entry><literal>Cuneiform</literal></entry>
</row>
<row>
<entry><literal>Cypriot</literal></entry>
<entry><literal>Cyrillic</literal></entry>
<entry><literal>Deseret</literal></entry>
<entry><literal>Devanagari</literal></entry>
<entry><literal>Egyptian_Hieroglyphs</literal></entry>
</row>
<row>
<entry><literal>Ethiopic</literal></entry>
<entry><literal>Georgian</literal></entry>
<entry><literal>Glagolitic</literal></entry>
<entry><literal>Gothic</literal></entry>
<entry><literal>Greek</literal></entry>
</row>
<row>
<entry><literal>Gujarati</literal></entry>
<entry><literal>Gurmukhi</literal></entry>
<entry><literal>Han</literal></entry>
<entry><literal>Hangul</literal></entry>
<entry><literal>Hanunoo</literal></entry>
</row>
<row>
<entry><literal>Hebrew</literal></entry>
<entry><literal>Hiragana</literal></entry>
<entry><literal>Imperial_Aramaic</literal></entry>
<entry><literal>Inherited</literal></entry>
<entry><literal>Inscriptional_Pahlavi</literal></entry>
</row>
<row>
<entry><literal>Inscriptional_Parthian</literal></entry>
<entry><literal>Javanese</literal></entry>
<entry><literal>Kaithi</literal></entry>
<entry><literal>Kannada</literal></entry>
<entry><literal>Katakana</literal></entry>
</row>
<row>
<entry><literal>Kayah_Li</literal></entry>
<entry><literal>Kharoshthi</literal></entry>
<entry><literal>Khmer</literal></entry>
<entry><literal>Lao</literal></entry>
<entry><literal>Latin</literal></entry>
</row>
<row>
<entry><literal>Lepcha</literal></entry>
<entry><literal>Limbu</literal></entry>
<entry><literal>Linear_B</literal></entry>
<entry><literal>Lisu</literal></entry>
<entry><literal>Lycian</literal></entry>
</row>
<row>
<entry><literal>Lydian</literal></entry>
<entry><literal>Malayalam</literal></entry>
<entry><literal>Mandaic</literal></entry>
<entry><literal>Meetei_Mayek</literal></entry>
<entry><literal>Meroitic_Cursive</literal></entry>
</row>
<row>
<entry><literal>Meroitic_Hieroglyphs</literal></entry>
<entry><literal>Miao</literal></entry>
<entry><literal>Mongolian</literal></entry>
<entry><literal>Myanmar</literal></entry>
<entry><literal>New_Tai_Lue</literal></entry>
</row>
<row>
<entry><literal>Nko</literal></entry>
<entry><literal>Ogham</literal></entry>
<entry><literal>Old_Italic</literal></entry>
<entry><literal>Old_Persian</literal></entry>
<entry><literal>Old_South_Arabian</literal></entry>
</row>
<row>
<entry><literal>Old_Turkic</literal></entry>
<entry><literal>Ol_Chiki</literal></entry>
<entry><literal>Oriya</literal></entry>
<entry><literal>Osmanya</literal></entry>
<entry><literal>Phags_Pa</literal></entry>
</row>
<row>
<entry><literal>Phoenician</literal></entry>
<entry><literal>Rejang</literal></entry>
<entry><literal>Runic</literal></entry>
<entry><literal>Samaritan</literal></entry>
<entry><literal>Saurashtra</literal></entry>
</row>
<row>
<entry><literal>Sharada</literal></entry>
<entry><literal>Shavian</literal></entry>
<entry><literal>Sinhala</literal></entry>
<entry><literal>Sora_Sompeng</literal></entry>
<entry><literal>Sundanese</literal></entry>
</row>
<row>
<entry><literal>Syloti_Nagri</literal></entry>
<entry><literal>Syriac</literal></entry>
<entry><literal>Tagalog</literal></entry>
<entry><literal>Tagbanwa</literal></entry>
<entry><literal>Tai_Le</literal></entry>
</row>
<row>
<entry><literal>Tai_Tham</literal></entry>
<entry><literal>Tai_Viet</literal></entry>
<entry><literal>Takri</literal></entry>
<entry><literal>Tamil</literal></entry>
<entry><literal>Telugu</literal></entry>
</row>
<row>
<entry><literal>Thaana</literal></entry>
<entry><literal>Thai</literal></entry>
<entry><literal>Tibetan</literal></entry>
<entry><literal>Tifinagh</literal></entry>
<entry><literal>Ugaritic</literal></entry>
</row>
<row>
<entry><literal>Vai</literal></entry>
<entry><literal>Yi</literal></entry>
<entry />
<entry />
<entry />
</row>
</tbody>
</tgroup>
</table>
<para>
La secuencia de escape <literal>\X</literal> coincide con un grupo de glifos extendidos de Unicode. Un grupo de glifos extendidos de Unicode es uno o más caracteres Unicode
que se combinan para formar un glifo. En efecto, esto puede considerarse como
el equivalente de Unicode de <literal>.</literal> ya que coincidirá con un
carácter compuesto, independientemente de cuántos caracteres individuales se
utilicen realmente para renderizarlo.
</para>
<para>
En versiones de PCRE anteriores a 8.32 (que corresponde a versiones de PHP anteriores a 5.4.14 cuando se usa la biblioteca PCRE incluida), <literal>\X</literal>
es equivalente a <literal>(?>\PM\pM*)</literal>. Es decir, coincide con un carácter sin la propiedad "marca", seguido de cero o más caracteres
con la propiedad "marca", y trata la secuencia como un grupo atómico (ver más abajo). Los caracteres con la propiedad "marca" son típicamente acentos que afectan al carácter anterior.
</para>
<para>
Coincidir con caracteres por propiedad Unicode no es rápido, porque PCRE tiene
que buscar una estructura que contiene datos para más de quince mil
caracteres. Por eso las secuencias de escape tradicionales como
<literal>\d</literal> y <literal>\w</literal> no usan propiedades Unicode
en PCRE.
</para>
</section>
<section xml:id="regexp.reference.anchors">
<title>Anclajes</title>
<para>
Fuera de una clase de caracteres, en el modo de coincidencia predeterminado, el
carácter de circunflejo (<literal>^</literal>) es una afirmación que
es verdadera solo si el punto de coincidencia actual está al inicio
de la cadena de sujeto. Dentro de una clase de caracteres, el circunflejo (<literal>^</literal>)
tiene un significado completamente diferente (ver más abajo).
</para>
<para>
El circunflejo (<literal>^</literal>) no necesita ser el primer carácter
del patrón si se involucran varias alternativas, pero
debe ser la primera cosa en cada alternativa en la que aparezca
si el patrón alguna vez va a coincidir con esa rama. Si todas las alternativas posibles comienzan con un circunflejo (<literal>^</literal>), es decir,
si el patrón está restringido a coincidir solo al inicio del sujeto,
se dice que está "anclado". (También hay otras
construcciones que pueden causar que un patrón esté anclado.)
</para>
<para>
Un carácter de dólar (<literal>$</literal>) es una afirmación que es
&true; solo si el punto de coincidencia actual está al final
de la cadena de sujeto, o inmediatamente antes de un carácter de nueva línea que es el último
carácter en la cadena (por defecto). El dólar (<literal>$</literal>)
no necesita ser el último carácter del patrón si se involucran varias alternativas, pero
debe ser el último elemento en cualquier rama
en la que aparezca. El dólar no tiene ningún significado especial en una
clase de caracteres.
</para>
<para>
El significado del dólar puede cambiarse para que solo coincida
al final muy exacto de la cadena, estableciendo la
<link linkend="reference.pcre.pattern.modifiers">opción PCRE_DOLLAR_ENDONLY</link>
en el momento de compilación o coincidencia. Esto no afecta la afirmación \Z.
</para>
<para>
Los significados de los caracteres de circunflejo y dólar cambian si la
<link linkend="reference.pcre.pattern.modifiers">opción PCRE_MULTILINE</link> está establecida. Cuando esto es así, coinciden inmediatamente después y
inmediatamente antes de un carácter "\n" interno, respectivamente, además de coincidir al inicio y final de la cadena de sujeto. Por ejemplo, el patrón /^abc$/ coincide con la cadena de sujeto "def\nabc" en modo multiline,
pero no de otra manera. Por lo tanto, los patrones que están anclados en modo de una sola línea porque todas las ramas comienzan con "^" no están anclados en modo multiline. La
<link linkend="reference.pcre.pattern.modifiers">opción PCRE_DOLLAR_ENDONLY</link>
se ignora si
<link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link> está
establecido.
</para>
<para>
Tenga en cuenta que las secuencias \A, \Z y \z pueden usarse para coincidir
con el inicio y final del sujeto en ambos modos, y si todas
las ramas de un patrón comienzan con \A, siempre está anclado,
ya sea que <link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link>
esté establecido o no.
</para>
</section>
<section xml:id="regexp.reference.dot">
<title>Punto</title>
<para>
Fuera de una clase de caracteres, un punto en el patrón coincide con cualquier
carácter en el sujeto, incluyendo un carácter no imprimible,
pero no (por defecto) un salto de línea. Si la
<link linkend="reference.pcre.pattern.modifiers">opción PCRE_DOTALL</link> está establecida, entonces los puntos coinciden con saltos de línea también. El
manejo del punto es completamente independiente del manejo de circunflejo y dólar, la única relación siendo que ambos involucran caracteres de salto de línea. El punto no tiene ningún significado especial
en una clase de caracteres.
</para>
<para>
<emphasis>\C</emphasis> puede usarse para coincidir con un solo byte. Tiene sentido
en <emphasis>modo UTF-8</emphasis> donde el punto completo coincide con el carácter completo que puede consistir en múltiples bytes.
</para>
</section>
<section xml:id="regexp.reference.character-classes">
<title>Clases de caracteres</title>
<para>
Un corchete de apertura introduce una clase de caracteres,
terminada por un corchete de cierre. Un corchete de cierre por sí solo no es especial. Si se requiere un corchete de cierre como miembro de la clase, debe ser
el primer carácter de datos en la clase (después de un circunflejo inicial, si está presente) o escapado con una barra invertida.
</para>
<para>
Una clase de caracteres coincide con un solo carácter en el sujeto;
el carácter debe estar en el conjunto de caracteres definido por
la clase, a menos que el primer carácter en la clase sea un
circunflejo, en cuyo caso el carácter del sujeto no debe estar en
el conjunto definido por la clase. Si se requiere un circunflejo como
miembro de la clase, asegúrese de que no sea el
primer carácter, o escápelo con una barra invertida.
</para>
<para>
Por ejemplo, la clase de caracteres [aeiou] coincide con cualquier vocal minúscula, mientras que [^aeiou] coincide con cualquier carácter que no sea
una vocal minúscula. Tenga en cuenta que un circunflejo es solo una
notación conveniente para especificar los caracteres que están en
la clase enumerando aquellos que no están. No es una
afirmación: aún consume un carácter de la cadena de sujeto,
y falla si el puntero actual está al final
de la cadena.
</para>
<para>
Cuando se establece la coincidencia sin distinción de mayúsculas y minúsculas, cualquier letra
en una clase representa tanto su versión mayúscula como minúscula,
por lo que, por ejemplo, una [aeiou] insensible coincide con "A"
así como con "a", y una [^aeiou] insensible no coincide
con "A", mientras que una versión sensible (con distinción de mayúsculas y minúsculas) sí.
</para>
<para>
El carácter de nueva línea nunca se trata de manera especial en
clases de caracteres, independientemente de la configuración de las opciones <link
linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link>
o <link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link>. Una clase como [^a] siempre coincide con una nueva línea.
</para>
<para>
El carácter de guión puede usarse para especificar un rango
de caracteres en una clase de caracteres. Por ejemplo, [d-m]
coincide con cualquier letra entre d y m, inclusive. Si se requiere un carácter de guión en una clase, debe escaparse con una
barra invertida o aparecer en una posición donde no pueda
interpretarse como indicación de un rango, típicamente como el primer o último
carácter en la clase.
</para>
<para>
No es posible tener el carácter literal "]" como el
carácter final de un rango. Un patrón como [W-]46] es
interpretado como una clase de dos caracteres ("W" y "-")
seguido de una cadena literal "46]", por lo que coincidiría con "W46]" o
"-46]". Sin embargo, si el "]" se escapa con una barra invertida, se interpreta como el final del rango, por lo que [W-\]46] es
interpretado como una sola clase que contiene un rango seguido de dos
caracteres separados. También se puede usar la representación octal o hexadecimal
de "]" para terminar un rango.
</para>
<para>
Los rangos operan en la secuencia de clasificación ASCII. También pueden usarse para caracteres especificados numéricamente, por ejemplo
[\000-\037]. Si se usa un rango que incluye letras cuando se establece la
coincidencia sin distinción de mayúsculas y minúsculas, coincide con
las letras en cualquier caso. Por ejemplo, [W-c] es equivalente a
[][\^_`wxyzabc], coincidiendo sin distinción de mayúsculas y minúsculas, y si se usan tablas de caracteres para la configuración regional "fr", [\xc8-\xcb] coincide
con caracteres E acentuados en ambos casos.
</para>
<para>
Los tipos de caracteres \d, \D, \s, \S, \w, y \W también
pueden aparecer en una clase de caracteres, y añaden los caracteres que
coinciden a la clase. Por ejemplo, [\dABCDEF] coincide con cualquier
dígito hexadecimal. Un circunflejo puede usarse convenientemente
con los tipos de caracteres mayúsculas para especificar un conjunto más
restringido de caracteres que el tipo minúscula correspondiente.
Por ejemplo, la clase [^\W_] coincide con cualquier letra o dígito,
pero no con el guión bajo.
</para>
<para>
Todos los caracteres no alfanuméricos excepto \, -, ^ (al inicio) y el terminador ] son no especiales en clases de caracteres, pero no causa daño si están escapados. El terminador del patrón es siempre especial y debe escaparse cuando se usa
dentro de una expresión.
</para>
<para>
Perl soporta la notación POSIX para clases de caracteres. Esta usa nombres
encerrados por <literal>[:</literal> y <literal>:]</literal> dentro
de los corchetes de apertura y cierre. PCRE también
soporta esta notación. Por ejemplo, <literal>[01[:alpha:]%]</literal>
coincide con "0", "1", cualquier carácter alfabético, o "%". Las clases de nombres soportadas son:
<table>
<title>Clases de caracteres</title>
<tgroup cols="2">
<tbody>
<row><entry><literal>alnum</literal></entry><entry>letras y dígitos</entry></row>
<row><entry><literal>alpha</literal></entry><entry>letras</entry></row>
<row><entry><literal>ascii</literal></entry><entry>códigos de caracteres 0 - 127</entry></row>
<row><entry><literal>blank</literal></entry><entry>solo espacio o tabulación</entry></row>
<row><entry><literal>cntrl</literal></entry><entry>caracteres de control</entry></row>
<row><entry><literal>digit</literal></entry><entry>dígitos decimales (igual que \d)</entry></row>
<row><entry><literal>graph</literal></entry><entry>caracteres de impresión, excluyendo espacio</entry></row>
<row><entry><literal>lower</literal></entry><entry>letras minúsculas</entry></row>
<row><entry><literal>print</literal></entry><entry>caracteres de impresión, incluyendo espacio</entry></row>
<row><entry><literal>punct</literal></entry><entry>caracteres de impresión, excluyendo letras y dígitos</entry></row>
<row><entry><literal>space</literal></entry><entry>espacio en blanco (no exactamente igual que \s)</entry></row>
<row><entry><literal>upper</literal></entry><entry>letras mayúsculas</entry></row>
<row><entry><literal>word</literal></entry><entry>caracteres de "palabra" (igual que \w)</entry></row>
<row><entry><literal>xdigit</literal></entry><entry>dígitos hexadecimales</entry></row>
</tbody>
</tgroup>
</table>
Los caracteres <literal>space</literal> son HT (9), LF (10), VT (11), FF (12), CR (13),
y espacio (32). Observe que esta lista incluye el carácter VT (código
11). Esto hace que "space" sea diferente a <literal>\s</literal>, que no incluye VT (para compatibilidad con Perl).
</para>
<para>
El nombre <literal>word</literal> es una extensión de Perl, y <literal>blank</literal> es una extensión de GNU
de Perl 5.8. Otra extensión de Perl es la negación, que se indica
con un carácter <literal>^</literal> después de los dos puntos. Por ejemplo,
<literal>[12[:^digit:]]</literal> coincide con "1", "2", o cualquier no dígito.
</para>
<para>
En modo UTF-8, los caracteres con valores mayores que 128 no coinciden con ninguna
de las clases de caracteres POSIX.
A partir de libpcre 8.10, algunas clases de caracteres se cambian para usar
propiedades de caracteres Unicode, en cuyo caso la restricción mencionada no se aplica. Consulte el <link xlink:href="&url.pcre.man;">manual PCRE(3)</link>
para obtener más detalles.
</para>
<para>
Las propiedades de caracteres Unicode pueden aparecer dentro de una clase de caracteres. No pueden ser parte de un rango. El carácter de guión después de una clase de caracteres Unicode coincidirá literalmente. Intentar terminar un rango con una propiedad de caracteres Unicode resultará en una advertencia.
</para>
</section>
<section xml:id="regexp.reference.alternation">
<title>Alternancia</title>
<para>
Los caracteres de barra vertical se usan para separar patrones alternativos.
Por ejemplo, el patrón
<literal>gilbert|sullivan</literal>
coincide con "gilbert" o "sullivan". Cualquier número de alternativas
puede aparecer, y se permite una alternativa vacía
(coincidiendo con la cadena vacía). El proceso de coincidencia intenta
cada alternativa en orden, de izquierda a derecha, y la primera
que tenga éxito se usa. Si las alternativas están dentro de un
subpatrón (definido más abajo), "éxito" significa coincidir con
el resto del patrón principal así como con la alternativa en el
subpatrón.
</para>
<para>
Es posible registrar cuál alternativa fue coincidente usando
<literal>(*MARK:NAME)</literal> o <literal>(*:NAME)</literal>.
Cualquier número de verbos <literal>(*MARK)</literal> pueden aparecer y sus nombres no tienen que ser únicos. Cuando una coincidencia tiene éxito, el nombre de la última <literal>(*MARK:NAME)</literal> encontrada se colocará entre las coincidencias como si fuera un grupo de captura llamado <literal>MARK</literal> para que pueda leerse desde el <parameter>matches</parameter> de
<function>preg_match</function> y se pasará al
<parameter>callback</parameter> de <function>preg_replace_callback</function> etc.
</para>
</section>
<section xml:id="regexp.reference.internal-options">
<title>Configuración de opciones internas</title>
<para>
La configuración de <link linkend="reference.pcre.pattern.modifiers">PCRE_CASELESS</link>,
<link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link>,
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link>,
<link linkend="reference.pcre.pattern.modifiers">PCRE_UNGREEDY</link>,
<link linkend="reference.pcre.pattern.modifiers">PCRE_EXTRA</link>,
<link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link>
y PCRE_DUPNAMES puede cambiarse desde dentro del patrón mediante
una secuencia de letras de opciones de Perl encerradas entre "(?" y
")". Las letras de opciones son:
<table>
<title>Letras de opciones internas</title>
<tgroup cols="2">
<tbody>
<row>
<entry><literal>i</literal></entry>
<entry>para <link linkend="reference.pcre.pattern.modifiers">PCRE_CASELESS</link></entry>
</row>
<row>
<entry><literal>m</literal></entry>
<entry>para <link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link></entry>
</row>
<row>
<entry><literal>s</literal></entry>
<entry>para <link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link></entry>
</row>
<row>
<entry><literal>x</literal></entry>
<entry>para <link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link></entry>
</row>
<row>
<entry><literal>U</literal></entry>
<entry>para <link linkend="reference.pcre.pattern.modifiers">PCRE_UNGREEDY</link></entry>
</row>
<row>
<entry><literal>X</literal></entry>
<entry>para <link linkend="reference.pcre.pattern.modifiers">PCRE_EXTRA</link>
(ya no soportado a partir de PHP 7.3.0)</entry>
</row>
<row>
<entry><literal>J</literal></entry>
<entry>para <link linkend="reference.pcre.pattern.modifiers">PCRE_INFO_JCHANGED</link></entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
Por ejemplo, (?im) establece coincidencia sin distinción de mayúsculas y minúsculas, multiline. También es posible anular estas opciones precediendo la letra
con un guión, y una configuración combinada como
(?im-sx), que establece <link
linkend="reference.pcre.pattern.modifiers">PCRE_CASELESS</link> y
<link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link>
mientras anula <link
linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link> y
<link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link>,
también está permitido. Si una letra aparece tanto antes como después del
guión, la opción se anula.
</para>
<para>
Cuando ocurre un cambio de opción a nivel superior (es decir, no dentro
de paréntesis de subpatrón), el cambio se aplica al resto del
patrón que sigue. Por lo tanto, <literal>/ab(?i)c/</literal> coincide solo con "abc"
y "abC".
</para>
<para>
Si un cambio de opción ocurre dentro de un subpatrón, el efecto
es diferente. Este es un cambio de comportamiento en Perl 5.005.
Un cambio de opción dentro de un subpatrón afecta solo a esa parte
del subpatrón que sigue, por lo que
<literal>(a(?i)b)c</literal>
coincide con "abc" y "aBc" y ninguna otra cadena (asumiendo <link
linkend="reference.pcre.pattern.modifiers">PCRE_CASELESS</link> no se usa). De esta manera, las opciones pueden tener diferentes configuraciones en
diferentes partes del patrón. Cualquier cambio realizado en una alternativa se
lleva a las ramas posteriores dentro del mismo subpatrón. Por
ejemplo,
<literal>(a(?i)b|c)</literal>
coincide con "ab", "aB", "c", y "C", incluso cuando se coincide
con "C" la primera rama se abandona antes de la configuración de la opción.
Esto se debe a que los efectos de la configuración de las opciones ocurren al
tiempo de compilación. Habría un comportamiento muy extraño de otra manera.
</para>
<para>
Las opciones específicas de PCRE <link
linkend="reference.pcre.pattern.modifiers">PCRE_UNGREEDY</link> y
<link linkend="reference.pcre.pattern.modifiers">PCRE_EXTRA</link> pueden
cambiarse de la misma manera que las opciones compatibles con Perl usando las letras U y X respectivamente. La configuración de la bandera
(?X) es especial en que siempre debe ocurrir antes en
el patrón que cualquiera de las características adicionales que activa,
incluso cuando está a nivel superior. Es mejor ponerla al principio.
</para>
</section>
<section xml:id="regexp.reference.subpatterns">
<title>Subpatrones</title>
<para>
Los subpatrones están delimitados por paréntesis (paréntesis redondos),
que pueden anidarse. Marcar una parte de un patrón como subpatrón
hace dos cosas:
</para>
<orderedlist>
<listitem>
<para>
Localiza un conjunto de alternativas. Por ejemplo, el patrón
<literal>cat(aract|erpillar|)</literal> coincide con una de las palabras "cat",
"cataract", o "caterpillar". Sin los paréntesis, coincidiría
con "cataract", "erpillar" o la cadena vacía.
</para>
</listitem>
<listitem>
<para>
Establece el subpatrón como un subpatrón de captura (como se definió anteriormente).
Cuando todo el patrón coincide, la porción de la cadena de sujeto
que coincidió con el subpatrón se devuelve al llamador a través del
argumento <emphasis>ovector</emphasis> de <function>pcre_exec</function>.
Los paréntesis de apertura se cuentan de izquierda a derecha (comenzando desde 1) para
obtener los números de los subpatrones de captura.
</para>
</listitem>
</orderedlist>
<para>
Por ejemplo, si la cadena "the red king" se compara con
el patrón
<literal>the ((red|white) (king|queen))</literal>
las subcadenas capturadas son "red king", "red", y "king",
y están numeradas 1, 2, y 3.
</para>
<para>
El hecho de que los paréntesis simples cumplan dos funciones no
siempre es útil. Hay momentos en los que se requiere un subpatrón de agrupación
sin un requisito de captura. Si un paréntesis de apertura es seguido por "?:", el subpatrón no
realiza ninguna captura, y no se cuenta al calcular el número de cualquier subpatrón de captura posterior. Por ejemplo, si la cadena "the white queen" se compara con
el patrón
<literal>the ((?:red|white) (king|queen))</literal>
las subcadenas capturadas son "white queen" y "queen", y
están numeradas 1 y 2. El número máximo de subcadenas capturadas
es 65535. Puede que no sea posible compilar patrones tan grandes,
sin embargo, dependiendo de las opciones de configuración de libpcre.
</para>
<para>
Como abreviatura conveniente, si se requieren configuraciones de opciones
al inicio de un subpatrón no de captura, las letras de opciones pueden aparecer entre
el "?" y el ":". Por lo tanto, los dos patrones
</para>
<informalexample>
<programlisting>
<![CDATA[
(?i:saturday|sunday)
(?:(?i)saturday|sunday)
]]>
</programlisting>
</informalexample>
<para>
coinciden exactamente con el mismo conjunto de cadenas. Debido a que las ramas alternativas se prueban de izquierda a derecha, y las opciones no se restablecen hasta que se alcanza el final del subpatrón, una configuración de opción en una rama afecta a las ramas posteriores, por lo que los patrones anteriores coinciden con "SUNDAY" así como con "Saturday".
</para>
<para>
Es posible nombrar un subpatrón usando la sintaxis
<literal>(?P&lt;name&gt;pattern)</literal>. Este subpatrón luego
será indexado en el array de coincidencias por su posición numérica normal y
también por nombre. Hay dos sintaxis alternativas
<literal>(?&lt;name&gt;pattern)</literal> y <literal>(?'name'pattern)</literal>.
</para>
<para>
A veces es necesario tener múltiples coincidencias alternativas
en una expresión regular. Normalmente, cada una de estas tendría
su propio número de referencia inversa, aunque solo una de ellas podría coincidir.
Para superar esto, la sintaxis <literal>(?|</literal> permite tener números duplicados. Considere el siguiente regex aplicado a la cadena <literal>Sunday</literal>:
</para>
<informalexample>
<programlisting>
<![CDATA[(?:(Sat)ur|(Sun))day]]>
</programlisting>
</informalexample>
<para>
Aquí <literal>Sun</literal> se almacena en la referencia inversa 2, mientras que
la referencia inversa 1 está vacía. Hacer coincidir <literal>Saturday</literal> produce
<literal>Sat</literal> en la referencia inversa 1 mientras que la referencia inversa 2 no existe. Cambiar el patrón para usar <literal>(?|</literal> resuelve este problema:
</para>
<informalexample>
<programlisting>
<![CDATA[(?|(Sat)ur|(Sun))day]]>
</programlisting>
</informalexample>
<para>
Usando este patrón, tanto <literal>Sun</literal> como <literal>Sat</literal>
se almacenarían en la referencia inversa 1.
</para>
</section>
<section xml:id="regexp.reference.repetition">
<title>Repetición</title>
<para>
La repetición se especifica mediante cuantificadores, que pueden seguir cualquiera
de los siguientes elementos:
<itemizedlist>
<listitem><simpara>un solo carácter, posiblemente escapado</simpara></listitem>
<listitem><simpara>el metacarácter .</simpara></listitem>
<listitem><simpara>una clase de caracteres</simpara></listitem>
<listitem><simpara>una referencia inversa (ver siguiente sección)</simpara></listitem>
<listitem><simpara>un subpatrón entre paréntesis (a menos que sea una afirmación -
ver más abajo)</simpara></listitem>
</itemizedlist>
</para>
<para>
El cuantificador general de repetición especifica un número mínimo y máximo de coincidencias permitidas, dando los dos
números entre llaves (llaves), separados por una coma.
Los números deben ser menores que 65536, y el primero debe ser
menor o igual al segundo. Por ejemplo:
<literal>z{2,4}</literal>
coincide con "zz", "zzz", o "zzzz". Una llave de cierre por sí sola
no es un carácter especial. Si el segundo número se omite,
pero la coma está presente, no hay límite superior; si el
segundo número y la coma se omiten ambos, el cuantificador
especifica un número exacto de coincidencias requeridas. Por lo tanto
<literal>[aeiou]{3,}</literal>
coincide con al menos 3 vocales sucesivas, pero puede coincidir con
muchas más, mientras que
<literal>\d{8}</literal>
coincide con exactamente 8 dígitos.
</para>
<simpara>
Antes de PHP 8.4.0, una llave de apertura que
aparece en una posición donde no se permite un cuantificador, o
una que no coincide con la sintaxis de un cuantificador, se toma
como un carácter literal. Por ejemplo, <literal>{,6}</literal>
no es un cuantificador, sino una cadena literal de cuatro caracteres.
A partir de PHP 8.4.0, la extensión PCRE se incluye con la versión PCRE2 10.44,
que permite patrones como <literal>\d{,8}</literal> y se interpretan como <literal>\d{0,8}</literal>.
Además, a partir de PHP 8.4.0, los caracteres de espacio alrededor de los cuantificadores como
<literal>\d{0 , 8}</literal> y <literal>\d{ 0 , 8 }</literal> están permitidos.
</simpara>
<para>
El cuantificador {0} está permitido, lo que hace que la expresión se comporte como si el elemento anterior y el cuantificador no estuvieran presentes.
</para>
<para>
Para mayor comodidad (y compatibilidad histórica) los tres cuantificadores más comunes tienen abreviaturas de un solo carácter:
<table>
<title>Cuantificadores de un solo carácter</title>
<tgroup cols="2">
<tbody>
<row>
<entry><literal>*</literal></entry>
<entry>equivalente a <literal>{0,}</literal></entry>
</row>
<row>
<entry><literal>+</literal></entry>
<entry>equivalente a <literal>{1,}</literal></entry>
</row>
<row>
<entry><literal>?</literal></entry>
<entry>equivalente a <literal>{0,1}</literal></entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
Es posible construir bucles infinitos siguiendo un subpatrón que puede coincidir con cero caracteres con un cuantificador que no tiene límite superior, por ejemplo:
<literal>(a?)*</literal>
</para>
<para>
Versiones anteriores de Perl y PCRE solían dar un error en el momento de la compilación para tales patrones. Sin embargo, dado que hay casos en los que esto puede ser útil, tales patrones ahora son aceptados, pero si alguna repetición del subpatrón en realidad coincide con cero caracteres, el bucle se rompe a la fuerza.
</para>
<para>
Por defecto, los cuantificadores son "codiciosos", es decir, coinciden con la mayor cantidad posible (hasta el número máximo de veces permitido), sin causar que el resto del patrón
falle. El ejemplo clásico donde esto causa problemas es al intentar coincidir con comentarios en programas C. Estos aparecen entre
las secuencias /* y */ y dentro de la secuencia, los caracteres individuales
* y / pueden aparecer. Un intento de coincidir con comentarios C aplicando el patrón
<literal>/\*.*\*/</literal>
a la cadena
<literal>/* first comment */ not comment /* second comment */</literal>
falla, porque coincide con toda la cadena debido a la codicia del elemento .*.
</para>
<para>
Sin embargo, si un cuantificador es seguido por un signo de interrogación,
entonces se vuelve perezoso, y en su lugar coincide con el número mínimo de veces posible, por lo que el patrón
<literal>/\*.*?\*/</literal>
hace lo correcto con los comentarios C. El significado de los varios cuantificadores no cambia de otra manera, solo el número preferido de coincidencias. No confunda este uso de
signo de interrogación con su uso como cuantificador por sí mismo.
Debido a que tiene dos usos, a veces puede aparecer duplicado, como en
<literal>\d??\d</literal>
que coincide con un dígito por preferencia, pero puede coincidir con dos si
esa es la única manera de que el resto del patrón coincida.
</para>
<para>
Si la <link linkend="reference.pcre.pattern.modifiers">opción PCRE_UNGREEDY</link>
está establecida (una opción que no
está disponible en Perl) entonces los cuantificadores no son codiciosos por defecto, pero los individuales pueden hacerse codiciosos siguiendo
con un signo de interrogación. En otras palabras, invierte el comportamiento por defecto.
</para>
<para>
Los cuantificadores seguidos de <literal>+</literal> son "poseídos". Consumen
tantos caracteres como sea posible y no regresan para hacer coincidir el resto del
patrón. Por lo tanto, <literal>.*abc</literal> coincide con "aabc" pero
<literal>.*+abc</literal> no porque <literal>.*+</literal> consume toda la cadena. Los cuantificadores poseídos pueden usarse para acelerar el procesamiento.
</para>
<para>
Cuando un subpatrón entre paréntesis se cuantifica con un conteo de repetición mínimo que es mayor que 1 o con un máximo limitado,
se requiere más almacenamiento para el patrón compilado, en
proporción al tamaño del mínimo o máximo.
</para>
<para>
Si un patrón comienza con .* o .{0,} y la <link
linkend="reference.pcre.pattern.modifiers">opción PCRE_DOTALL</link> está establecida (equivalente a /s de Perl), lo que permite que el punto coincida con saltos de línea, entonces el patrón está implícitamente anclado,
porque lo que sigue se intentará contra cada posición de carácter en la cadena de sujeto, por lo que no tiene sentido volver a intentar la coincidencia general en cualquier posición después de la primera.
PCRE trata un patrón como si estuviera precedido por \A.
En casos donde se sabe que la cadena de sujeto no contiene saltos de línea, se obtiene una optimización estableciendo <link
linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link> cuando el patrón comienza con .* para
obtener esta optimización, o
alternativamente usando ^ para indicar el anclaje explícitamente.
</para>
<para>
Cuando un subpatrón de captura se repite, el valor capturado es la subcadena que coincidió con la iteración final. Por ejemplo, después de
<literal>(tweedle[dume]{3}\s*)+</literal>
ha coincidido con "tweedledum tweedledee" el valor de la subcadena capturada es "tweedledee". Sin embargo, si hay
subpatrones de captura anidados, los valores capturados correspondientes pueden haber sido establecidos en iteraciones anteriores. Por ejemplo,
después de
<literal>/(a|(b))+/</literal>
coincide con "aba" el valor de la segunda subcadena capturada es
"b".
</para>
</section>
<section xml:id="regexp.reference.back-references">
<title>Referencias inversas</title>
<para>
Fuera de una clase de caracteres, una barra invertida seguida de un dígito
mayor que 0 (y posiblemente otros dígitos) es una referencia inversa a un subpatrón de captura anterior (es decir, a su
izquierda) en el patrón, siempre que haya habido tantos subpatrones de apertura de captura anteriores.
</para>
<para>
Sin embargo, si el número decimal que sigue a la barra invertida es
menor que 10, siempre se toma como una referencia inversa, y causa un error solo si no hay tantos paréntesis de apertura de captura en todo el patrón. En otras palabras, los
paréntesis a los que se hace referencia no necesitan estar a la izquierda de la referencia para números menores que 10.
Una "referencia inversa hacia adelante" puede tener sentido cuando se involucra una repetición y el subpatrón a la derecha ha participado
en una iteración anterior. Consulte la sección
<link linkend="regexp.reference.escape">secuencias de escape</link> para obtener más detalles sobre el manejo de los dígitos que siguen a una barra invertida.
</para>
<para>
Una referencia inversa coincide con lo que realmente coincidió con el subpatrón de captura en la cadena de sujeto actual, en lugar de
cualquier cosa que coincida con el subpatrón mismo. Por lo tanto, el patrón
<literal>(sens|respons)e and \1ibility</literal>
coincide con "sense and sensibility" y "response and responsibility",
pero no con "sense and responsibility". Si la coincidencia sensible (con distinción de mayúsculas y minúsculas) está en vigor en el momento de la referencia inversa, entonces
el caso de las letras es relevante. Por ejemplo,
<literal>((?i)rah)\s+\1</literal>
coincide con "rah rah" y "RAH RAH", pero no con "RAH rah", incluso
aunque el subpatrón de captura original se coincidió sin distinción de mayúsculas y minúsculas.
</para>
<para>
Puede haber más de una referencia inversa al mismo subpatrón.
Si un subpatrón no se ha utilizado realmente en
una coincidencia particular, entonces cualquier referencia inversa a él siempre
falla. Por ejemplo, el patrón
<literal>(a|(bc))\2</literal>
siempre falla si comienza a coincidir con "a" en lugar de "bc".
Debido a que pueden haber hasta 99 referencias inversas, todos los dígitos
que siguen a la barra invertida se toman como parte de un número de referencia inversa potencial. Si el patrón continúa con un carácter de dígito,
entonces algún delimitador debe usarse para terminar la referencia inversa. Si la <link
linkend="reference.pcre.pattern.modifiers">opción PCRE_EXTENDED</link> está establecida, esto puede ser espacio en blanco. De lo contrario, se puede usar un comentario vacío.
</para>
<para>
Una referencia inversa que ocurre dentro de los paréntesis a los que se refiere falla cuando el subpatrón se usa por primera vez, por lo que, por
ejemplo, (a\1) nunca coincide. Sin embargo, tales referencias pueden ser útiles dentro de subpatrones repetidos. Por ejemplo, el patrón
<literal>(a|b\1)+</literal>
coincide con cualquier número de "a" y también "aba", "ababba" etc. En cada iteración del subpatrón, la referencia inversa coincide
con la cadena de caracteres 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 referencia inversa. Esto se puede hacer usando alternancia, como en el
ejemplo anterior, o por un cuantificador con un mínimo de cero.
</para>
<para>
La secuencia de escape <literal>\g</literal> puede usarse para referencias absolutas y relativas de subpatrones.
Esta secuencia de escape debe ir seguida de un número sin signo o un número negativo, opcionalmente encerrado entre llaves. Las secuencias <literal>\1</literal>,
<literal>\g1</literal> y <literal>\g{1}</literal> son sinónimas
entre sí. El uso de este patrón con un número sin signo puede ayudar a eliminar la ambigüedad inherente al usar dígitos después de una barra invertida. La secuencia ayuda a distinguir referencias inversas de caracteres octales y también facilita tener una referencia inversa seguida de un número literal, por ejemplo <literal>\g{2}1</literal>.
</para>
<para>
El uso de la secuencia <literal>\g</literal> con un número negativo
significa una referencia relativa. Por ejemplo, <literal>(foo)(bar)\g{-1}</literal>
coincidiría con la secuencia "foobarbar" y <literal>(foo)(bar)\g{-2}</literal>
coincide con "foobarfoo". Esto puede ser útil en patrones largos como una alternativa a llevar la cuenta del número de subpatrones para referirse
a un subpatrón específico anterior.
</para>
<para>
Las referencias inversas a los subpatrones con nombre pueden lograrse mediante
<literal>(?P=name)</literal>,
<literal>\k&lt;name&gt;</literal>, <literal>\k'name'</literal>,
<literal>\k{name}</literal>, <literal>\g{name}</literal>,
<literal>\g&lt;name&gt;</literal> o <literal>\g'name'</literal>.
</para>
</section>
<section xml:id="regexp.reference.assertions">
<title>Afirmaciones</title>
<para>
Una afirmación es una prueba sobre los caracteres que siguen o preceden al punto de coincidencia actual que no consume realmente ningún carácter. Las afirmaciones simples codificadas como \b,
\B, \A, \Z, \z, ^ y $ se describen en <link linkend="regexp.reference.escape">secuencias de escape</link>. Las afirmaciones más complicadas se codifican como subpatrones. Hay dos
tipos: aquellos que <emphasis>miran hacia adelante</emphasis> de la posición actual en la
cadena de sujeto, y aquellos que <emphasis>miran hacia atrás</emphasis> de ella.
</para>
<para>
Un subpatrón de afirmación se coincide de la manera normal, excepto
que no hace que la posición de coincidencia actual cambie. <emphasis>Afirmaciones de anticipación</emphasis> comienzan con (?= para afirmaciones positivas y (?! para afirmaciones negativas. Por ejemplo,
<literal>\w+(?=;)</literal>
coincide con una palabra seguida de un punto y coma, pero no incluye
el punto y coma en la coincidencia, y
<literal>foo(?!bar)</literal>
coincide con cualquier ocurrencia de "foo" que no esté seguida por
"bar". Tenga en cuenta que el patrón aparentemente similar
<literal>(?!foo)bar</literal>
no encuentra una ocurrencia de "bar" que esté precedida por algo que no sea "foo"; encuentra cualquier ocurrencia de "bar"
en absoluto, porque la afirmación (?!foo) es siempre &true;
cuando los siguientes tres caracteres son "bar". Se necesita una afirmación de retroceso para lograr este efecto.
</para>
<para>
<emphasis>Afirmaciones de retroceso</emphasis> comienzan con (?&lt;= para afirmaciones positivas y (?&lt;! para afirmaciones negativas. Por ejemplo,
<literal>(?&lt;!foo)bar</literal>
sí encuentra una ocurrencia de "bar" que no está precedida por
"foo". El contenido de una afirmación de retroceso está restringido
de tal manera que todas las cadenas que coincide deben tener una longitud fija. Sin embargo, si hay varias alternativas, no todas tienen que tener la misma longitud fija. Por lo tanto
<literal>(?&lt;=bullock|donkey)</literal>
está permitido, pero
<literal>(?&lt;!dogs?|cats?)</literal>
causa un error en el momento de la compilación. Las ramas que coinciden con cadenas de diferentes longitudes están permitidas solo al nivel superior
de una afirmación de retroceso. Esto es una extensión en comparación con Perl 5.005, que requiere que todas las ramas coincidan con la misma longitud de cadena. Una afirmación como
<literal>(?&lt;=ab(c|de))</literal>
no está permitida, porque su única rama de nivel superior puede coincidir con dos longitudes diferentes, pero es aceptable si se reescribe para usar dos ramas de nivel superior:
<literal>(?&lt;=abc|abde)</literal>
La implementación de afirmaciones de retroceso es, para cada alternativa, mover temporalmente la posición actual hacia atrás por el ancho fijo y luego intentar coincidir. Si no hay suficientes caracteres antes de la posición actual, la coincidencia se considera fallida. Los retrocesos en conjunto con subpatrones de una sola vez pueden ser particularmente útiles para coincidir al final de las cadenas; se da un ejemplo al final
de la sección sobre subpatrones de una sola vez.
</para>
<para>
Varias afirmaciones (de cualquier tipo) pueden ocurrir en sucesión.
Por ejemplo,
<literal>(?&lt;=\d{3})(?&lt;!999)foo</literal>
coincide con "foo" precedido por tres dígitos que no son "999".
Observe que cada una de las afirmaciones se aplica independientemente
en el mismo punto de la cadena de sujeto. Primero hay una verificación de que los tres caracteres anteriores son todos dígitos,
luego hay una verificación de que los mismos tres caracteres no son "999". Este patrón no coincide con "foo" precedido por seis
caracteres, el primero de los cuales son dígitos y los últimos tres de los cuales no son "999". Por ejemplo, no coincide
con "123abcfoo". Un patrón para hacer eso es
<literal>(?&lt;=\d{3}...)(?&lt;!999)foo</literal>
</para>
<para>
Esta vez la primera afirmación mira los seis caracteres anteriores, verificando que los primeros tres son dígitos, y
luego la segunda afirmación verifica que los tres caracteres anteriores no son "999".
</para>
<para>
Las afirmaciones pueden anidarse en cualquier combinación. Por ejemplo,
<literal>(?&lt;=(?&lt;!foo)bar)baz</literal>
coincide con una ocurrencia de "baz" que es precedida por "bar"
que a su vez no es precedida por "foo", mientras que
<literal>(?&lt;=\d{3}...(?&lt;!999))foo</literal>
es otro patrón que coincide con "foo" precedido por tres
dígitos y cualquier tres caracteres que no son "999".
</para>
<para>
Los subpatrones de afirmación no son subpatrones de captura, y no pueden
repetirse, porque no tiene sentido afirmar lo mismo varias veces. Si cualquier tipo de afirmación contiene subpatrones de captura dentro de ella, estos se cuentan para los fines de numerar los subpatrones de captura en todo
el patrón. Sin embargo, la captura de subcadenas solo se lleva a cabo para afirmaciones positivas, porque no tiene sentido para afirmaciones negativas.
</para>
<para>
Las afirmaciones cuentan hacia el máximo de 200 subpatrones entre paréntesis.
</para>
</section>
<section xml:id="regexp.reference.onlyonce">
<title>Subpatrones de una sola vez</title>
<para>
Con la repetición de maximización y minimización, el fracaso de lo que sigue normalmente hace que el elemento repetido se reevalúe para ver si un número diferente de repeticiones permite que el resto del patrón coincida. A veces es útil
evitar esto, ya sea para cambiar la naturaleza de la coincidencia, o
para hacer que falle antes de lo que lo haría de otra manera, cuando el autor del patrón sabe que no hay punto en continuar.
</para>
<para>
Considere, por ejemplo, el patrón \d+foo cuando se aplica a
la línea de sujeto
<literal>123456bar</literal>
</para>
<para>
Después de coincidir con todos los 6 dígitos y luego fallar al coincidir con "foo",
la acción normal del coincidente es intentar nuevamente con solo 5
dígitos coincidiendo con el elemento \d+, y luego con 4, y así sucesivamente,
antes de fallar finalmente. Los subpatrones de una sola vez proporcionan el medio para especificar que una vez que una parte del patrón ha coincidido, no debe ser revaluada de esta manera, por lo que el coincidente se rendiría inmediatamente al fallar en coincidir con "foo"
la primera vez. La notación es otro tipo de paréntesis especial, comenzando con (?&gt; como en este ejemplo:
<literal>(?&gt;\d+)bar</literal>
</para>
<para>
Este tipo de paréntesis "bloquea" la parte del patrón que contiene una vez que ha coincidido, y un fallo más adelante en el patrón se impide retroceder hacia él.
Retroceder más allá de él, sin embargo, funciona como de costumbre.
</para>
<para>
Una descripción alternativa es que un subpatrón de este tipo
coincide con la cadena de caracteres que un patrón independiente idéntico coincidiría, si se anclara en el punto
actual en la cadena de sujeto.
</para>
<para>
Los subpatrones de una sola vez no son subpatrones de captura. Casos simples como el ejemplo anterior pueden pensarse como un repetidor maximizador que debe tragarse todo lo que pueda. Por lo tanto,
mientras que tanto \d+ como \d+? están dispuestos a ajustar el número de dígitos que coinciden para hacer que el resto del patrón coincida, (?&gt;\d+) solo puede coincidir con una secuencia completa de dígitos.
</para>
<para>
Esta construcción puede contener, por supuesto, subpatrones arbitrariamente complejos, y puede anidarse.
</para>
<para>
Los subpatrones de una sola vez pueden usarse en conjunto con afirmaciones de retroceso para especificar coincidencias eficientes al final de la cadena de sujeto. Considere un patrón simple como
<literal>abcd$</literal>
cuando se aplica a una cadena larga que no coincide. Dado que la coincidencia procede de izquierda a derecha, PCRE buscará cada "a" en el sujeto y luego verá si lo que sigue coincide con el resto del patrón. Si el patrón se especifica como
<literal>^.*abcd$</literal>
entonces el .* inicial coincide con toda la cadena al principio, pero
cuando esto falla (porque no hay un "a" siguiente), retrocede para coincidir con todo excepto el último carácter, luego todo excepto los dos últimos caracteres, y así sucesivamente. Una vez más, la búsqueda de "a" cubre toda la cadena, de derecha a izquierda, por lo que no estamos mejor. Sin embargo, si el patrón se escribe como
<literal>^(?>.*)(?&lt;=abcd)</literal>
entonces no puede haber retroceso para el elemento .*; solo puede coincidir con toda la cadena. La afirmación de retroceso posterior realiza una sola prueba en los últimos cuatro caracteres. Si falla, la coincidencia falla inmediatamente. Para cadenas largas,
este enfoque hace una diferencia significativa en el tiempo de procesamiento.
</para>
<para>
Cuando un patrón contiene una repetición ilimitada dentro de un subpatrón que a su vez puede repetirse un número ilimitado de veces, el uso de un subpatrón de una sola vez es la única manera de evitar que algunas coincidencias fallidas tomen un tiempo muy largo. El patrón
<literal>(\D+|&lt;\d+>)*[!?]</literal>
coincide con un número ilimitado de subcadenas que consisten en no dígitos, o dígitos encerrados en &lt;>, seguido de
! o ?. Cuando coincide, funciona rápidamente. Sin embargo, si se aplica a
<literal>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</literal>
tarda mucho tiempo en informar el fallo. Esto se debe a
que la cadena puede dividirse entre las dos repeticiones de muchas maneras, y todas tienen que ser probadas antes de que se pueda informar el fallo. (El ejemplo usó [!?] en lugar de un solo carácter al final,
porque tanto PCRE como Perl tienen una optimización que permite un fallo rápido cuando se usa un solo carácter. Recuerdan el último carácter único que se requiere para una coincidencia, y fallan temprano si no está presente en la cadena.)
Si el patrón se cambia a
<literal>((?>\D+)|&lt;\d+>)*[!?]</literal>
las secuencias de no dígitos no pueden romperse, y el fallo ocurre rápidamente.
</para>
</section>
<section xml:id="regexp.reference.conditional">
<title>Subpatrones condicionales</title>
<para>
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
</para>
<informalexample>
<programlisting>
<![CDATA[
(?(condition)yes-pattern)
(?(condition)yes-pattern|no-pattern)
]]>
</programlisting>
</informalexample>
<para>
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.
</para>
<para>
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 <link
linkend="reference.pcre.pattern.modifiers">opción PCRE_EXTENDED</link>
y para dividirlo en tres partes para facilitar la discusión):
</para>
<informalexample>
<programlisting>
<![CDATA[
( \( )? [^()]+ (?(1) \) )
]]>
</programlisting>
</informalexample>
<para>
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.
</para>
<para>
Si la condición es la cadena <literal>(R)</literal>, se cumple si se ha realizado una llamada recursiva al patrón o subpatrón. En "nivel superior", la condición es falsa.
</para>
<para>
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:
</para>
<informalexample>
<programlisting>
<![CDATA[
(?(?=[^a-z]*[a-z])
\d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )
]]>
</programlisting>
</informalexample>
<para>
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.
</para>
</section>
<section xml:id="regexp.reference.comments">
<title>Comentarios</title>
<para>
La secuencia (?# marca el inicio de un comentario que
continúa hasta el siguiente paréntesis de cierre. No se permiten paréntesis anidados. Los caracteres que componen un
comentario no participan en absoluto en la coincidencia del patrón.
</para>
<para>
Si la <link linkend="reference.pcre.pattern.modifiers">opción PCRE_EXTENDED</link> está establecida, un carácter # no escapado fuera de una clase de caracteres
introduce un comentario que continúa hasta el siguiente carácter de nueva línea en el patrón.
</para>
<para>
<example>
<title>Uso de comentarios en el patrón PCRE</title>
<programlisting role="php">
<![CDATA[
<?php
$subject = 'test';
/* (?# puede usarse para agregar comentarios sin habilitar PCRE_EXTENDED */
$match = preg_match('/te(?# este es un comentario)st/', $subject);
var_dump($match);
/* El espacio en blanco y # se trata como parte del patrón a menos que PCRE_EXTENDED esté habilitado */
$match = preg_match('/te #~~~~
st/', $subject);
var_dump($match);
/* Cuando PCRE_EXTENDED está habilitado, todos los caracteres de espacio en blanco y cualquier cosa
que siga a un # no escapado en la misma línea se ignoran */
$match = preg_match('/te #~~~~
st/x', $subject);
var_dump($match);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
int(1)
int(0)
int(1)
]]>
</screen>
</example>
</para>
</section>
<section xml:id="regexp.reference.recursive">
<title>Patrones recursivos</title>
<para>
Considere el problema de hacer coincidir una cadena entre paréntesis,
permitiendo paréntesis anidados ilimitados. Sin el uso
de recursión, lo mejor que se puede hacer es usar un patrón
que coincide hasta una profundidad fija de anidamiento. No
es posible manejar una profundidad de anidamiento arbitraria. Perl 5.6 ha
proporcionado una instalación experimental que permite que las expresiones regulares sean recursivas (entre otras cosas). Se proporciona el elemento especial (?R) para el caso específico de recursión.
Este patrón PCRE resuelve el problema de los paréntesis (asumiendo
que la <link linkend="reference.pcre.pattern.modifiers">opción PCRE_EXTENDED</link> está establecida para que el espacio en blanco se
ignore):
<literal>\( ( (?>[^()]+) | (?R) )* \)</literal>
</para>
<para>
Primero coincide con un paréntesis de apertura. Luego coincide con cualquier
número de subcadenas que pueden ser una secuencia de caracteres no paréntesis, o una coincidencia recursiva del patrón mismo (es decir, una subcadena correctamente entre paréntesis). Finalmente hay un paréntesis de cierre.
</para>
<para>
Este ejemplo de patrón en particular contiene repeticiones ilimitadas anidadas, y por lo tanto el uso de un subpatrón de una sola vez para coincidir con cadenas de caracteres no paréntesis es importante al aplicar
el patrón a cadenas que no coinciden. Por ejemplo, cuando se aplica a
<literal>(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()</literal>
produce "no coincide" rápidamente. Sin embargo, si no se usa un subpatrón de una sola vez, la coincidencia tarda un tiempo muy largo
porque hay tantas formas diferentes en que las repeticiones + y * pueden dividir el sujeto, y todas tienen que ser probadas antes de que se pueda informar el fallo.
</para>
<para>
Los valores establecidos para cualquier subpatrón de captura son aquellos del nivel más externo de la recursión en el que se establece el valor del subpatrón. Si el patrón anterior coincide con
<literal>(ab(cd)ef)</literal>
el valor para los paréntesis de captura es "ef", que es el último valor tomado en el nivel superior. Si se añaden más paréntesis, dando
<literal>\( ( ( (?>[^()]+) | (?R) )* ) \)</literal>
entonces la cadena que capturan
es "ab(cd)ef", el contenido de los paréntesis de nivel superior. Si hay más de 15 paréntesis de captura en un patrón,
PCRE tiene que obtener memoria adicional para almacenar datos durante una
recursión, lo cual hace mediante el uso de pcre_malloc, liberándola posteriormente mediante pcre_free. Si no se puede obtener memoria, solo guarda datos para los primeros 15 subpatrones de captura, ya que no hay forma de dar un error de memoria insuficiente desde dentro de una recursión.
</para>
<para>
<literal>(?1)</literal>, <literal>(?2)</literal> y así sucesivamente pueden usarse para subpatrones recursivos también. También es posible usar subpatrones con nombre: <literal>(?P&gt;name)</literal> o
<literal>(?&amp;name)</literal>.
</para>
<para>
Si la sintaxis para una referencia de subpatrón recursivo (ya sea por número o por nombre) se usa fuera de los paréntesis a los que se refiere, opera como una subrutina en un lenguaje de programación. Un ejemplo anterior señaló que el patrón
<literal>(sens|respons)e and \1ibility</literal>
coincide con "sense and sensibility" y "response and responsibility", pero
no con "sense and responsibility". Si en su lugar se usa el patrón
<literal>(sens|respons)e and (?1)ibility</literal>
sí coincide con "sense and responsibility" además de las otras dos cadenas. Tales referencias deben, sin embargo, seguir al subpatrón al que se refieren.
</para>
<para>
La longitud máxima de una cadena de sujeto es el número positivo más grande
que puede contener una variable entera. Sin embargo, PCRE usa recursión para
manejar subpatrones y repetición indefinida. Esto significa que el espacio de pila disponible puede limitar el tamaño de una cadena de sujeto que puede ser
procesada por ciertos patrones.
</para>
</section>
<section xml:id="regexp.reference.performance">
<title>Rendimiento</title>
<para>
Ciertos elementos que pueden aparecer en patrones son más eficientes
que otros. Es más eficiente usar una clase de caracteres como [aeiou] que un conjunto de alternativas como (a|e|i|o|u).
En general, la construcción más simple que proporciona el
comportamiento requerido suele ser la más eficiente. El libro de Jeffrey
Friedl contiene mucha discusión sobre cómo optimizar expresiones regulares para un rendimiento eficiente.
</para>
<para>
Cuando un patrón comienza con .* y la <link
linkend="reference.pcre.pattern.modifiers">opción PCRE_DOTALL</link> está
establecida, el patrón está implícitamente anclado por PCRE, ya que
solo puede coincidir al inicio de una cadena de sujeto. Sin embargo, si
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link> no está establecida, PCRE no puede hacer esta optimización,
porque el metacarácter . no coincide entonces con un salto de línea,
y si la cadena de sujeto contiene saltos de línea, el patrón puede
coincidir desde el carácter inmediatamente después de uno de ellos
en lugar de desde el principio. Por ejemplo, el patrón
<literal>(.*) second</literal>
coincide con la cadena de sujeto "first\nand second" (donde \n representa
un carácter de nueva línea) con la primera subcadena capturada siendo
"and". Para hacer esto, PCRE tiene que volver a intentar la coincidencia
comenzando después de cada salto de línea en el sujeto.
</para>
<para>
Si está utilizando un patrón como este con cadenas de sujeto que no contienen saltos de línea, el mejor rendimiento se obtiene estableciendo <link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link>,
o comenzando el patrón con ^.* para
indicar anclaje explícito. Esto ahorra a PCRE tener que escanear a lo largo del sujeto buscando un salto de línea para reiniciar.
</para>
<para>
Tenga cuidado con los patrones que contienen repeticiones indefinidas anidadas.
Estos pueden tardar mucho tiempo en ejecutarse cuando se aplican a una cadena
que no coincide. Considere el fragmento de patrón
<literal>(a+)*</literal>
</para>
<para>
Esto puede coincidir con "aaaa" de 33 maneras diferentes, y este número
aumenta muy rápidamente a medida que la cadena se alarga. (La repetición *
puede coincidir 0, 1, 2, 3 o 4 veces, y para cada uno de
esos casos excepto 0, las repeticiones + pueden coincidir con diferentes
números de veces.) Cuando el resto del patrón es tal que
toda la coincidencia va a fallar, PCRE en principio
tiene que probar cada variación posible, y esto puede tomar un
tiempo extremadamente largo.
</para>
<para>
Una optimización atrapa algunos de los casos más simples como
<literal>(a+)*b</literal>
donde un carácter literal sigue. Antes de embarcarse en el
procedimiento de coincidencia estándar, PCRE verifica que hay una "b"
más adelante en el sujeto, y si no la hay, falla la coincidencia inmediatamente. Sin embargo, cuando no hay un carácter literal siguiente, esta optimización no puede usarse. Puede ver la diferencia comparando el comportamiento de
<literal>(a+)*\d</literal>
con el patrón anterior. El primero da un fallo casi
instantáneamente cuando se aplica a una línea completa de caracteres "a",
mientras que el segundo tarda un tiempo apreciable con cadenas
más largas que unas 20 caracteres.
</para>
</section>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->