"re" --- Operaciones con expresiones regulares
**********************************************

**Source code:** Lib/re/

======================================================================

Este módulo proporciona operaciones de coincidencia de expresiones
regulares similares a las encontradas en Perl.

Both patterns and strings to be searched can be Unicode strings
("str") as well as 8-bit strings ("bytes"). However, Unicode strings
and 8-bit strings cannot be mixed: that is, you cannot match a Unicode
string with a bytes pattern or vice-versa; similarly, when asking for
a substitution, the replacement string must be of the same type as
both the pattern and the search string.

Las expresiones regulares usan el carácter de barra inversa ("'\'")
para indicar formas especiales o para permitir el uso de caracteres
especiales sin invocar su significado especial.  Esto choca con el uso
de Python de este carácter para el mismo propósito con los literales
de cadena; por ejemplo, para hacer coincidir una barra inversa
literal, se podría escribir "'\\\\'" como patrón, porque la expresión
regular debe ser "\\", y cada barra inversa debe ser expresada como
"\\" dentro de un literal de cadena regular de Python.  También, notar
que cualquier secuencia de escape inválida mientras se use la barra
inversa de Python en los literales de cadena ahora genera un
"DeprecationWarning" y en el futuro esto se convertirá en un
"SyntaxError".  Este comportamiento ocurrirá incluso si es una
secuencia de escape válida para una expresión regular.

La solución es usar la notación de cadena *raw* de Python para los
patrones de expresiones regulares; las barras inversas no se manejan
de ninguna manera especial en un literal de cadena prefijado con
"'r'".  Así que "r"\n"" es una cadena de dos caracteres que contiene
"'\'" y "'n'", mientras que ""\n"" es una cadena de un carácter que
contiene una nueva línea.  Normalmente los patrones se expresan en
código Python usando esta notación de cadena *raw*.

Es importante señalar que la mayoría de las operaciones de expresiones
regulares están disponibles como funciones y métodos a nivel de módulo
en expresiones regulares compiladas (expresiones regulares
compiladas).  Las funciones son atajos que no requieren de compilar un
objeto regex primero, aunque pasan por alto algunos parámetros de
ajuste.

Ver también:

  El módulo de terceros regex , cuenta con una API compatible con el
  módulo de la biblioteca estándar "re", el cual ofrece una
  funcionalidad adicional y un soporte Unicode más completo.


Sintaxis de expresiones regulares
=================================

Una expresión regular (o RE, por sus siglas en inglés) especifica un
conjunto de cadenas que coinciden con ella; las funciones de este
módulo permiten comprobar si una determinada cadena coincide con una
expresión regular dada (o si una expresión regular dada coincide con
una determinada cadena, que se reduce a lo mismo).

Las expresiones regulares pueden ser concatenadas para formar nuevas
expresiones regulares; si *A* y *B* son ambas expresiones regulares,
entonces *AB* es también una expresión regular. En general, si una
cadena *p* coincide con *A* y otra cadena *q* coincide con *B*, la
cadena *porque* coincidirá con AB.  Esto se mantiene a menos que *A* o
*B* contengan operaciones de baja precedencia; condiciones límite
entre *A* y *B*; o tengan referencias de grupo numeradas.  Así, las
expresiones complejas pueden construirse fácilmente a partir de
expresiones primitivas más simples como las que se describen aquí.
Para detalles de la teoría e implementación de las expresiones
regulares, consulte el libro de Friedl [Frie09], o casi cualquier
libro de texto sobre la construcción de compiladores.

A continuación se explica brevemente el formato de las expresiones
regulares.  Para más información y una presentación más amena,
consultar la Expresiones regulares COMOS (HOWTO).

Las expresiones regulares pueden contener tanto caracteres especiales
como ordinarios. La mayoría de los caracteres ordinarios, como "'A'",
"'a'", o "'0'" son las expresiones regulares más sencillas;
simplemente se ajustan a sí mismas.  Se pueden concatenar caracteres
ordinarios, así que "last" coincide con la cadena "'last'".  (En el
resto de esta sección, se escribirán los RE en "este estilo especial",
normalmente sin comillas, y las cadenas que deban coincidir "'entre
comillas simples'".)

Algunos caracteres, como "'|'" o "'('", son especiales. Los caracteres
especiales representan clases de caracteres ordinarios, o afectan a la
forma en que se interpretan las expresiones regulares que los rodean.

Repetition operators or quantifiers ("*", "+", "?", "{m,n}", etc)
cannot be directly nested. This avoids ambiguity with the non-greedy
modifier suffix "?", and with other modifiers in other
implementations. To apply a second repetition to an inner repetition,
parentheses may be used. For example, the expression "(?:a{6})*"
matches any multiple of six "'a'" characters.

Los caracteres especiales son:

"."
   (Punto.) En el modo predeterminado, esto coincide con cualquier
   carácter excepto con una nueva línea.  Si se ha especificado el
   indicador "DOTALL", esto coincide con cualquier carácter que
   incluya una nueva línea.

"^"
   (Circunflejo.)  Coincide con el comienzo de la cadena, y en modo
   "MULTILINE" también coincide inmediatamente después de cada nueva
   línea.

"$"
   Coincide con el final de la cadena o justo antes de la nueva línea
   al final de la cadena, y en modo "MULTILINE" también coincide antes
   de una nueva línea.  "foo" coincide con 'foo' y 'foobar', mientras
   que la expresión regular "foo$" sólo coincide con 'foo'.  Más
   interesante aún, al buscar "foo.$" en "'foo1\nfoo2\n'" coincide con
   'foo2' normalmente, pero solo 'foo1' en "MULTILINE`"; si busca un
   solo "$" en "'foo\n'" encontrará dos coincidencias (vacías): una
   justo antes de una nueva línea, y otra al final de la cadena.

"*"
   Hace que el RE resultante coincida con 0 o más repeticiones del RE
   precedente, tantas repeticiones como sean posibles.  "ab*"
   coincidirá con 'a', 'ab' o 'a' seguido de cualquier número de 'b'.

"+"
   Hace que la RE resultante coincida con 1 o más repeticiones de la
   RE precedente. "ab+" coincidirá con 'a' seguido de cualquier número
   distinto de cero de 'b'; no coincidirá solo con 'a'.

"?"
   Hace que la RE resultante coincida con 0 o 1 repeticiones de la RE
   precedente. "ab?" coincidirá con 'a' o 'ab'.

"*?", "+?", "??"
   The "'*'", "'+'", and "'?'" quantifiers are all *greedy*; they
   match as much text as possible.  Sometimes this behaviour isn't
   desired; if the RE "<.*>" is matched against "'<a> b <c>'", it will
   match the entire string, and not just "'<a>'".  Adding "?" after
   the quantifier makes it perform the match in *non-greedy* or
   *minimal* fashion; as *few* characters as possible will be matched.
   Using the RE "<.*?>" will match only "'<a>'".

"*+", "++", "?+"
   Like the "'*'", "'+'", and "'?'" quantifiers, those where "'+'" is
   appended also match as many times as possible. However, unlike the
   true greedy quantifiers, these do not allow back-tracking when the
   expression following it fails to match. These are known as
   *possessive* quantifiers. For example, "a*a" will match "'aaaa'"
   because the "a*" will match all 4 "'a'"s, but, when the final "'a'"
   is encountered, the expression is backtracked so that in the end
   the "a*" ends up matching 3 "'a'"s total, and the fourth "'a'" is
   matched by the final "'a'". However, when "a*+a" is used to match
   "'aaaa'", the "a*+" will match all 4 "'a'", but when the final
   "'a'" fails to find any more characters to match, the expression
   cannot be backtracked and will thus fail to match. "x*+", "x++" and
   "x?+" are equivalent to "(?>x*)", "(?>x+)" and "(?>x?)"
   correspondingly.

   Nuevo en la versión 3.11.

"{m}"
   Especifica que exactamente *m* copias de la RE anterior deben
   coincidir; menos coincidencias hacen que la RE entera no coincida.
   Por ejemplo, "a{6}" coincidirá exactamente con seis caracteres
   "'a'", pero no con cinco.

"{m,n}"
   Hace que el RE resultante coincida de *m* a *n* repeticiones del RE
   precedente, tratando de coincidir con el mayor número de
   repeticiones posible.  Por ejemplo, "a{3,5}" coincidirá de 3 a 5
   caracteres "'a'".  Omitiendo *m* se especifica un límite inferior
   de cero, y omitiendo *n* se especifica un límite superior infinito.
   Por ejemplo, "a{4,}b" coincidirá con "'aaaab'" o mil caracteres
   "'a'" seguidos de una "'b'", pero no "'aaab'". La coma no puede ser
   omitida o el modificador se confundiría con la forma descrita
   anteriormente.

"{m,n}?"
   Causes the resulting RE to match from *m* to *n* repetitions of the
   preceding RE, attempting to match as *few* repetitions as possible.
   This is the non-greedy version of the previous quantifier.  For
   example, on the 6-character string "'aaaaaa'", "a{3,5}" will match
   5 "'a'" characters, while "a{3,5}?" will only match 3 characters.

"{m,n}+"
   Causes the resulting RE to match from *m* to *n* repetitions of the
   preceding RE, attempting to match as many repetitions as possible
   *without* establishing any backtracking points. This is the
   possessive version of the quantifier above. For example, on the
   6-character string "'aaaaaa'", "a{3,5}+aa" attempt to match 5 "'a'"
   characters, then, requiring 2 more "'a'"s, will need more
   characters than available and thus fail, while "a{3,5}aa" will
   match with "a{3,5}" capturing 5, then 4 "'a'"s by backtracking and
   then the final 2 "'a'"s are matched by the final "aa" in the
   pattern. "x{m,n}+" is equivalent to "(?>x{m,n})".

   Nuevo en la versión 3.11.

"\"
   O bien se escapan a los caracteres especiales (lo que le permite
   hacer coincidir caracteres como "'*'", "'?'", y así sucesivamente),
   o se señala una secuencia especial; las secuencias especiales se
   explican más adelante.

   Si no se utiliza una cadena *raw* para expresar el patrón, recuerde
   que Python también utiliza la barra inversa como secuencia de
   escape en los literales de la cadena; si el analizador sintáctico
   de Python no reconoce la secuencia de escape, la barra inversa y el
   carácter subsiguiente se incluyen en la cadena resultante.  Sin
   embargo, si Python quisiera reconocer la secuencia resultante, la
   barra inversa debería repetirse dos veces.  Esto es complicado y
   difícil de entender, por lo que se recomienda encarecidamente
   utilizar cadenas *raw* para todas las expresiones salvo las más
   simples.

"[]"
   Se utiliza para indicar un conjunto de caracteres.  En un conjunto:

   * Los caracteres pueden ser listados individualmente, ej. "[amk]"
     coincidirá con "'a'", "'m'", o "'k'".

   * Los rangos de caracteres se pueden indicar mediante dos
     caracteres y separándolos con un "'-'". Por ejemplo, "[a-z]"
     coincidirá con cualquier letra ASCII en minúscula, "[0-5][0-9]"
     coincidirá con todos los números de dos dígitos desde el "00"
     hasta el "59", y "[0-9A-Fa-f]" coincidirá con cualquier dígito
     hexadecimal.  Si se escapa "-" (por ejemplo, "[a\-z]") o si se
     coloca como el primer o el último carácter (por ejemplo, "[-a]" o
     "[a-]"), coincidirá con un literal "'-'".

   * Los caracteres especiales pierden su significado especial dentro
     de los sets.  Por ejemplo, "[(+*)]" coincidirá con cualquiera de
     los caracteres literales "'('", "'+'", "'*'", o "')'".

   * Character classes such as "\w" or "\S" (defined below) are also
     accepted inside a set, although the characters they match depend
     on the flags used.

   * Los caracteres que no están dentro de un rango pueden ser
     coincidentes con *complementing* el conjunto. Si el primer
     carácter del conjunto es "'^'", todos los caracteres que *no*
     están en el conjunto coincidirán. Por ejemplo, "[^5]" coincidirá
     con cualquier carácter excepto con "'5'", y "[^^]" coincidirá con
     cualquier carácter excepto con "'^'". "^" no tiene un significado
     especial si no es el primer carácter del conjunto.

   * To match a literal "']'" inside a set, precede it with a
     backslash, or place it at the beginning of the set.  For example,
     both "[()[\]{}]" and "[]()[{}]" will match a right bracket, as
     well as left bracket, braces, and parentheses.

   * El soporte de conjuntos anidados y operaciones de conjuntos como
     en Unicode Technical Standard #18 podría ser añadido en el
     futuro. Esto cambiaría la sintaxis, así que por el momento se
     planteará un "FutureWarning" en casos ambiguos para facilitar
     este cambio. Ello incluye conjuntos que empiecen con un literal
     "'['" o que contengan secuencias de caracteres literales "'—'",
     "'&&'", "'~~'" y "'||'". Para evitar una advertencia, utilizar el
     código de escape con una barra inversa.

   Distinto en la versión 3.7: "FutureWarning" se genera si un
   conjunto de caracteres contiene construcciones que cambiarán
   semánticamente en el futuro.

"|"
   "A|B", donde *A* y *B* pueden ser RE arbitrarias, crea una
   expresión regular que coincidirá con *A* or *B*. Un número
   arbitrario de RE puede ser separado por "'|'" de esta manera. Esto
   puede también ser usado dentro de grupos (ver más adelante). Cuando
   la cadena de destino es procesada, los RE separados por "'|'" son
   probados de izquierda a derecha. Cuando un patrón coincide
   completamente, esa rama es aceptada. Esto significa que una vez que
   *A* coincida, *B* no se comprobará más, incluso si se produce una
   coincidencia general más larga. En otras palabras, el operador de
   "'|'" nunca es codicioso. Para emparejar un literal "'|'", se usa
   "\|", o se envuelve dentro de una clase de caracteres, como en
   "[|]".

"(...)"
   Coincide con cualquier expresión regular que esté dentro de los
   paréntesis, e indica el comienzo y el final de un grupo; el
   contenido de un grupo puede ser recuperado después de que se haya
   realizado una coincidencia, y puede coincidir más adelante en la
   cadena con la secuencia especial "\number", que se describe más
   adelante. Para hacer coincidir los literales "`'('" o "')'", se usa
   "\(" o "\)", o se envuelve dentro de una clase de caracteres:
   "[(]", "[)]".

"(?...)"
   Esta es una notación de extensión (un "'?'" después de un "'('" no
   tiene ningún otro significado). El primer carácter después de "'?'"
   determina el significado y la sintaxis de la construcción. Las
   extensiones normalmente no crean un nuevo grupo; "(?P<name>…)" es
   la única excepción a esta regla. A continuación se muestran las
   extensiones actualmente soportadas.

"(?aiLmsux)"
   (One or more letters from the set "'a'", "'i'", "'L'", "'m'",
   "'s'", "'u'", "'x'".) The group matches the empty string; the
   letters set the corresponding flags for the entire regular
   expression:

   * "re.A" (ASCII-only matching)

   * "re.I" (ignore case)

   * "re.L" (locale dependent)

   * "re.M" (multi-line)

   * "re.S" (dot matches all)

   * "re.U" (Unicode matching)

   * "re.X" (verbose)

   (The flags are described in Contenidos del módulo.) This is useful
   if you wish to include the flags as part of the regular expression,
   instead of passing a *flag* argument to the "re.compile()"
   function. Flags should be used first in the expression string.

   Distinto en la versión 3.11: Esta construcción solo se puede usar
   al comienzo de la expresión.

"(?:...)"
   Una versión no capturable de los paréntesis regulares. Hace
   coincidir cualquier expresión regular que esté dentro de los
   paréntesis, pero la subcadena coincidente con el grupo *no puede*
   ser recuperada después de realizar una coincidencia o referenciada
   más adelante en el patrón.

"(?aiLmsux-imsx:...)"
   (Zero or more letters from the set "'a'", "'i'", "'L'", "'m'",
   "'s'", "'u'", "'x'", optionally followed by "'-'" followed by one
   or more letters from the "'i'", "'m'", "'s'", "'x'".) The letters
   set or remove the corresponding flags for the part of the
   expression:

   * "re.A" (ASCII-only matching)

   * "re.I" (ignore case)

   * "re.L" (locale dependent)

   * "re.M" (multi-line)

   * "re.S" (dot matches all)

   * "re.U" (Unicode matching)

   * "re.X" (verbose)

   (The flags are described in Contenidos del módulo.)

   The letters "'a'", "'L'" and "'u'" are mutually exclusive when used
   as inline flags, so they can't be combined or follow "'-'".
   Instead, when one of them appears in an inline group, it overrides
   the matching mode in the enclosing group.  In Unicode patterns
   "(?a:...)" switches to ASCII-only matching, and "(?u:...)" switches
   to Unicode matching (default).  In bytes patterns "(?L:...)"
   switches to locale dependent matching, and "(?a:...)" switches to
   ASCII-only matching (default). This override is only in effect for
   the narrow inline group, and the original matching mode is restored
   outside of the group.

   Nuevo en la versión 3.6.

   Distinto en la versión 3.7: Las letras "'a'", "'L'" y "'u'" también
   pueden ser usadas en un grupo.

"(?>...)"
   Attempts to match "..." as if it was a separate regular expression,
   and if successful, continues to match the rest of the pattern
   following it. If the subsequent pattern fails to match, the stack
   can only be unwound to a point *before* the "(?>...)" because once
   exited, the expression, known as an *atomic group*, has thrown away
   all stack points within itself. Thus, "(?>.*)." would never match
   anything because first the ".*" would match all characters
   possible, then, having nothing left to match, the final "." would
   fail to match. Since there are no stack points saved in the Atomic
   Group, and there is no stack point before it, the entire expression
   would thus fail to match.

   Nuevo en la versión 3.11.

"(?P<name>...)"
   Similar a los paréntesis regulares, pero la subcadena coincidente
   con el grupo es accesible a través del nombre simbólico del grupo,
   *name* . Los nombres de grupo deben ser identificadores válidos de
   Python, y cada nombre de grupo debe ser definido sólo una vez
   dentro de una expresión regular.  Un grupo simbólico es también un
   grupo numerado, del mismo modo que si el grupo no tuviera nombre.

   Los grupos con nombre pueden ser referenciados en tres contextos.
   Si el patrón es "(?P<quote>['"]).*?(?P=quote)" (es decir, hacer
   coincidir una cadena citada con comillas simples o dobles):

   +-----------------------------------------+------------------------------------+
   | Contexto de la referencia al grupo      | Formas de hacer referencia         |
   | *quote* (cita)                          |                                    |
   |=========================================|====================================|
   | en el mismo patrón en sí mismo          | * "(?P=quote)" (como se muestra)   |
   |                                         | * "\1"                             |
   +-----------------------------------------+------------------------------------+
   | cuando se procesa el objeto de la       | * "m.group('quote')"  *            |
   | coincidencia *m*                        | "m.end('quote')" (etc.)            |
   +-----------------------------------------+------------------------------------+
   | en una cadena pasada al argumento       | * "\g<quote>"  * "\g<1>"  * "\1"   |
   | *repl* de "re.sub()"                    |                                    |
   +-----------------------------------------+------------------------------------+

   Obsoleto desde la versión 3.11: Group *name* containing characters
   outside the ASCII range ("b'\x00'"-"b'\x7f'") in "bytes" patterns.

"(?P=name)"
   Una referencia inversa a un grupo nombrado; coincide con cualquier
   texto correspondido por el grupo anterior llamado *name*.

"(?#...)"
   Un comentario; el contenido de los paréntesis es simplemente
   ignorado.

"(?=...)"
   Coincide si "…" coincide con el siguiente patrón, pero no procesa
   nada de la cadena. Esto se llama una *lookahead assertion*
   (aserción de búsqueda anticipada). Por ejemplo, "Isaac (?=Asimov)"
   coincidirá con "'Isaac '" sólo si va seguido de "'Asimov'".

"(?!...)"
   Coincide si "…" no coincide con el siguiente. Esta es una *negative
   lookahead assertion* (aserción negativa de búsqueda anticipada).
   Por ejemplo, "Isaac (?!Asimov)" coincidirá con "'Isaac '" sólo si
   *no* es seguido por "'Asimov'".

"(?<=...)"
   Coincide si la posición actual en la cadena es precedida por una
   coincidencia para "…" que termina en la posición actual.  Esto se
   llama una *positive lookbehind assertion* (aserciones positivas de
   búsqueda tardía). "(?<=abc)def" encontrará una coincidencia en
   "'abcdef'", ya que la búsqueda tardía hará una copia de seguridad
   de 3 caracteres y comprobará si el patrón contenido coincide. El
   patrón contenido sólo debe coincidir con cadenas de alguna longitud
   fija, lo que significa que "abc" o "a|b" están permitidas, pero
   "a*" y "a{3,4}" no lo están.  Hay que tener en cuenta que los
   patrones que empiezan con aserciones positivas de búsqueda tardía
   no coincidirán con el principio de la cadena que se está buscando;
   lo más probable es que se quiera usar la función "search()" en
   lugar de la función "match()":

   >>> import re
   >>> m = re.search('(?<=abc)def', 'abcdef')
   >>> m.group(0)
   'def'

   Este ejemplo busca una palabra seguida de un guión:

   >>> m = re.search(r'(?<=-)\w+', 'spam-egg')
   >>> m.group(0)
   'egg'

   Distinto en la versión 3.5: Se añadió soporte a las referencias de
   grupo de longitud fija.

"(?<!...)"
   Coincide si la posición actual en la cadena no está precedida por
   una coincidencia de "…".  Esto se llama una *negative lookbehind
   assertion* (Aserciones negativas de búsqueda tardía).  Similar a
   las aserciones positivas de búsqueda tardía, el patrón contenido
   sólo debe coincidir con cadenas de alguna longitud fija.  Los
   patrones que empiezan con aserciones negativas pueden coincidir al
   principio de la cadena que se busca.

"(?(id/name)yes-pattern|no-pattern)"
   Tratará de coincidir con el "yes-pattern" (con patrón) si el grupo
   con un *id* o  *nombre* existe, y con el "no-pattern" (sin patrón)
   si no existe. El "no-pattern" es opcional y puede ser omitido. Por
   ejemplo, "(<)?(\w+@\w+(?:\.\w+)+)(?(1)>||$)" es un patrón de
   coincidencia de correo electrónico deficiente, ya que coincidirá
   con "'<user@host.com>'" así como con "'user@host.com'", pero no con
   "'<user@host.com'" ni con "'user@host.com>'".

   Obsoleto desde la versión 3.11: Group *id* containing anything
   except ASCII digits. Group *name* containing characters outside the
   ASCII range ("b'\x00'"-"b'\x7f'") in "bytes" replacement strings.

Las secuencias especiales consisten en "'\'" y un carácter de la lista
que aparece más adelante. Si el carácter ordinario no es un dígito
ASCII o una letra ASCII, entonces el RE resultante coincidirá con el
segundo carácter.  Por ejemplo, "\$" coincide con el carácter "'$'".

"\number"
   Coincide con el contenido del grupo del mismo número.  Los grupos
   se numeran empezando por el 1. Por ejemplo, "(.+) \1" coincide con
   "'el el'" o "'55 55'", pero no con "'elel'" (notar el espacio
   después del grupo).  Esta secuencia especial sólo puede ser usada
   para hacer coincidir uno de los primeros 99 grupos.  Si el primer
   dígito del *número* es 0, o el *número* tiene 3 dígitos octales, no
   se interpretará como una coincidencia de grupo, sino como el
   carácter con valor octal *número*. Dentro de los "'['" y "']'" de
   una clase de caracteres, todos los escapes numéricos son tratados
   como caracteres.

"\A"
   Coincide sólo al principio de la cadena.

"\b"
   Matches the empty string, but only at the beginning or end of a
   word. A word is defined as a sequence of word characters. Note that
   formally, "\b" is defined as the boundary between a "\w" and a "\W"
   character (or vice versa), or between "\w" and the beginning or end
   of the string. This means that "r'\bat\b'" matches "'at'", "'at.'",
   "'(at)'", and "'as at ay'" but not "'attempt'" or "'atlas'".

   The default word characters in Unicode (str) patterns are Unicode
   alphanumerics and the underscore, but this can be changed by using
   the "ASCII" flag. Word boundaries are determined by the current
   locale if the "LOCALE" flag is used.

   Nota:

     Inside a character range, "\b" represents the backspace
     character, for compatibility with Python's string literals.

"\B"
   Matches the empty string, but only when it is *not* at the
   beginning or end of a word. This means that "r'at\B'" matches
   "'athens'", "'atom'", "'attorney'", but not "'at'", "'at.'", or
   "'at!'". "\B" is the opposite of "\b", so word characters in
   Unicode (str) patterns are Unicode alphanumerics or the underscore,
   although this can be changed by using the "ASCII" flag. Word
   boundaries are determined by the current locale if the "LOCALE"
   flag is used.

"\d"
   Para los patrones de Unicode (str):
      Matches any Unicode decimal digit (that is, any character in
      Unicode character category [Nd]). This includes "[0-9]", and
      also many other digit characters.

      Matches "[0-9]" if the "ASCII" flag is used.

   Para patrones de 8 bits (bytes):
      Matches any decimal digit in the ASCII character set; this is
      equivalent to "[0-9]".

"\D"
   Matches any character which is not a decimal digit. This is the
   opposite of "\d".

   Matches "[^0-9]" if the "ASCII" flag is used.

"\s"
   Para los patrones de Unicode (str):
      Matches Unicode whitespace characters (which includes "[
      \t\n\r\f\v]", and also many other characters, for example the
      non-breaking spaces mandated by typography rules in many
      languages).

      Matches "[ \t\n\r\f\v]" if the "ASCII" flag is used.

   Para patrones de 8 bits (bytes):
      Coincide con los caracteres considerados como espacios en blanco
      en el conjunto de caracteres ASCII, lo que equivale a "[
      \t\n\r\f\v]".

"\S"
   Matches any character which is not a whitespace character. This is
   the opposite of "\s".

   Matches "[^ \t\n\r\f\v]" if the "ASCII" flag is used.

"\w"
   Para los patrones de Unicode (str):
      Matches Unicode word characters; this includes all Unicode
      alphanumeric characters (as defined by "str.isalnum()"), as well
      as the underscore ("_").

      Matches "[a-zA-Z0-9_]" if the "ASCII" flag is used.

   Para patrones de 8 bits (bytes):
      Matches characters considered alphanumeric in the ASCII
      character set; this is equivalent to "[a-zA-Z0-9_]". If the
      "LOCALE" flag is used, matches characters considered
      alphanumeric in the current locale and the underscore.

"\W"
   Matches any character which is not a word character. This is the
   opposite of "\w". By default, matches non-underscore ("_")
   characters for which "str.isalnum()" returns "False".

   Matches "[^a-zA-Z0-9_]" if the "ASCII" flag is used.

   If the "LOCALE" flag is used, matches characters which are neither
   alphanumeric in the current locale nor the underscore.

"\Z"
   Coincide sólo el final de la cadena.

La mayoría de los escapes estándar soportados por los literales de la
cadena de Python también son aceptados por el analizador de
expresiones regulares:

   \a      \b      \f      \n
   \N      \r      \t      \u
   \U      \v      \x      \\

(Notar que "\b" se usa para representar los límites de las palabras, y
significa "retroceso" (*backspace*) sólo dentro de las clases de
caracteres.)

"'\u'", "'\U'", and "'\N'" escape sequences are only recognized in
Unicode (str) patterns. In bytes patterns they are errors. Unknown
escapes of ASCII letters are reserved for future use and treated as
errors.

Los escapes octales se incluyen en una forma limitada.  Si el primer
dígito es un 0, o si hay tres dígitos octales, se considera un escape
octal. De lo contrario, es una referencia de grupo.  En cuanto a los
literales de cadena, los escapes octales siempre tienen como máximo
tres dígitos de longitud.

Distinto en la versión 3.3: Se han añadido las secuencias de escape
"'\u'" y "'\U'".

Distinto en la versión 3.6: Los escapes desconocidos que consisten en
"'\'" y una letra ASCII ahora son errores.

Distinto en la versión 3.8: The "'\N{*name*}'" escape sequence has
been added. As in string literals, it expands to the named Unicode
character (e.g. "'\N{EM DASH}'").


Contenidos del módulo
=====================

El módulo define varias funciones, constantes y una excepción. Algunas
de las funciones son versiones simplificadas de los métodos completos
de las expresiones regulares compiladas.  La mayoría de las
aplicaciones no triviales utilizan siempre la forma compilada.


Indicadores
-----------

Distinto en la versión 3.6: Ahora las constantes de indicadores son
instancias de "RegexFlag", que es una subclase de "enum.IntFlag".

class re.RegexFlag

   Una clase "enum.IntFlag" contiene las opciones regex que se
   enumeran a continuación.

   Nuevo en la versión 3.11: - added to "__all__"

re.A
re.ASCII

   Make "\w", "\W", "\b", "\B", "\d", "\D", "\s" and "\S" perform
   ASCII-only matching instead of full Unicode matching.  This is only
   meaningful for Unicode (str) patterns, and is ignored for bytes
   patterns.

   Corresponds to the inline flag "(?a)".

   Nota:

     The "U" flag still exists for backward compatibility, but is
     redundant in Python 3 since matches are Unicode by default for
     "str" patterns, and Unicode matching isn't allowed for bytes
     patterns. "UNICODE" and the inline flag "(?u)" are similarly
     redundant.

re.DEBUG

   Display debug information about compiled expression.

   No corresponding inline flag.

re.I
re.IGNORECASE

   Perform case-insensitive matching; expressions like "[A-Z]" will
   also  match lowercase letters. Full Unicode matching (such as "Ü"
   matching "ü") also works unless the "ASCII" flag is used to disable
   non-ASCII matches. The current locale does not change the effect of
   this flag unless the "LOCALE" flag is also used.

   Corresponds to the inline flag "(?i)".

   Note that when the Unicode patterns "[a-z]" or "[A-Z]" are used in
   combination with the "IGNORECASE" flag, they will match the 52
   ASCII letters and 4 additional non-ASCII letters: 'İ' (U+0130,
   Latin capital letter I with dot above), 'ı' (U+0131, Latin small
   letter dotless i), 'ſ' (U+017F, Latin small letter long s) and 'K'
   (U+212A, Kelvin sign). If the "ASCII" flag is used, only letters
   'a' to 'z' and 'A' to 'Z' are matched.

re.L
re.LOCALE

   Make "\w", "\W", "\b", "\B" and case-insensitive matching dependent
   on the current locale. This flag can be used only with bytes
   patterns.

   Corresponds to the inline flag "(?L)".

   Advertencia:

     This flag is discouraged; consider Unicode matching instead. The
     locale mechanism is very unreliable as it only handles one
     "culture" at a time and only works with 8-bit locales. Unicode
     matching is enabled by default for Unicode (str) patterns and it
     is able to handle different locales and languages.

   Distinto en la versión 3.6: "LOCALE" can be used only with bytes
   patterns and is not compatible with "ASCII".

   Distinto en la versión 3.7: Compiled regular expression objects
   with the "LOCALE" flag no longer depend on the locale at compile
   time. Only the locale at matching time affects the result of
   matching.

re.M
re.MULTILINE

   When specified, the pattern character "'^'" matches at the
   beginning of the string and at the beginning of each line
   (immediately following each newline); and the pattern character
   "'$'" matches at the end of the string and at the end of each line
   (immediately preceding each newline).  By default, "'^'" matches
   only at the beginning of the string, and "'$'" only at the end of
   the string and immediately before the newline (if any) at the end
   of the string.

   Corresponds to the inline flag "(?m)".

re.NOFLAG

   Indicates no flag being applied, the value is "0".  This flag may
   be used as a default value for a function keyword argument or as a
   base value that will be conditionally ORed with other flags.
   Example of use as a default value:

      def myfunc(text, flag=re.NOFLAG):
          return re.match(text, flag)

   Nuevo en la versión 3.11.

re.S
re.DOTALL

   Make the "'.'" special character match any character at all,
   including a newline; without this flag, "'.'" will match anything
   *except* a newline.

   Corresponds to the inline flag "(?s)".

re.U
re.UNICODE

   In Python 3, Unicode characters are matched by default for "str"
   patterns. This flag is therefore redundant with **no effect** and
   is only kept for backward compatibility.

   See "ASCII" to restrict matching to ASCII characters instead.

re.X
re.VERBOSE

   This flag allows you to write regular expressions that look nicer
   and are more readable by allowing you to visually separate logical
   sections of the pattern and add comments. Whitespace within the
   pattern is ignored, except when in a character class, or when
   preceded by an unescaped backslash, or within tokens like "*?",
   "(?:" or "(?P<...>". For example, "(? :" and "* ?" are not allowed.
   When a line contains a "#" that is not in a character class and is
   not preceded by an unescaped backslash, all characters from the
   leftmost such "#" through the end of the line are ignored.

   Esto significa que los dos siguientes objetos expresión regular que
   coinciden con un número decimal son funcionalmente iguales:

      a = re.compile(r"""\d +  # the integral part
                         \.    # the decimal point
                         \d *  # some fractional digits""", re.X)
      b = re.compile(r"\d+\.\d*")

   Corresponde al indicador en línea "(?x)".


Funciones
---------

re.compile(pattern, flags=0)

   Compila un patrón de expresión regular en un objeto de expresión
   regular, que puede ser usado para las coincidencias usando
   "match()", "search()" y otros métodos, descritos más adelante.

   The expression's behaviour can be modified by specifying a *flags*
   value. Values can be any of the flags variables, combined using
   bitwise OR (the "|" operator).

   La secuencia

      prog = re.compile(pattern)
      result = prog.match(string)

   es equivalente a

      result = re.match(pattern, string)

   pero usando "re.compile()" y guardando el objeto resultante de la
   expresión regular para su reutilización es más eficiente cuando la
   expresión será usada varias veces en un solo programa.

   Nota:

     Las versiones compiladas de los patrones más recientes pasaron a
     "re.compile()" y las funciones de coincidencia a nivel de módulo
     están en caché, así que los programas que usan sólo unas pocas
     expresiones regulares a la vez no tienen que preocuparse de
     compilar expresiones regulares.

re.search(pattern, string, flags=0)

   Scan through *string* looking for the first location where the
   regular expression *pattern* produces a match, and return a
   corresponding "Match". Return "None" if no position in the string
   matches the pattern; note that this is different from finding a
   zero-length match at some point in the string.

re.match(pattern, string, flags=0)

   If zero or more characters at the beginning of *string* match the
   regular expression *pattern*, return a corresponding "Match".
   Return "None" if the string does not match the pattern; note that
   this is different from a zero-length match.

   Notar que incluso en el modo "MULTILINE", "re.match()" sólo
   coincidirá al principio de la cadena y no al principio de cada
   línea.

   Si se quiere localizar una coincidencia en cualquier lugar de la
   *string* ("cadena"), se utiliza "search()" en su lugar (ver también
   search() vs. match()).

re.fullmatch(pattern, string, flags=0)

   If the whole *string* matches the regular expression *pattern*,
   return a corresponding "Match".  Return "None" if the string does
   not match the pattern; note that this is different from a zero-
   length match.

   Nuevo en la versión 3.4.

re.split(pattern, string, maxsplit=0, flags=0)

   Divide la *string* ("cadena") por el número de ocurrencias del
   *pattern* ("patrón").  Si se utilizan paréntesis de captura en
   *pattern*, entonces el texto de todos los grupos en el patrón
   también se retornan como parte de la lista resultante. Si
   *maxsplit* (máxima divisibilidad) es distinta de cero, como mucho
   se producen *maxsplit* divisiones, y el resto de la cadena se
   retorna como elemento final de la lista.

      >>> re.split(r'\W+', 'Words, words, words.')
      ['Words', 'words', 'words', '']
      >>> re.split(r'(\W+)', 'Words, words, words.')
      ['Words', ', ', 'words', ', ', 'words', '.', '']
      >>> re.split(r'\W+', 'Words, words, words.', 1)
      ['Words', 'words, words.']
      >>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
      ['0', '3', '9']

   Si hay grupos de captura en el separador y coincide al principio de
   la cadena, el resultado comenzará con una cadena vacía.  Lo mismo
   ocurre con el final de la cadena:

      >>> re.split(r'(\W+)', '...words, words...')
      ['', '...', 'words', ', ', 'words', '...', '']

   De esa manera, los componentes de los separadores se encuentran
   siempre en los mismos índices relativos dentro de la lista de
   resultados.

   Las coincidencias vacías para el patrón dividen la cadena sólo
   cuando no están adyacentes a una coincidencia vacía anterior.

      >>> re.split(r'\b', 'Words, words, words.')
      ['', 'Words', ', ', 'words', ', ', 'words', '.']
      >>> re.split(r'\W*', '...words...')
      ['', '', 'w', 'o', 'r', 'd', 's', '', '']
      >>> re.split(r'(\W*)', '...words...')
      ['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']

   Distinto en la versión 3.1: Se añadió el argumento de los
   indicadores opcionales.

   Distinto en la versión 3.7: Se añadió el soporte de la división en
   un patrón que podría coincidir con una cadena vacía.

re.findall(pattern, string, flags=0)

   Retorna todas las coincidencias no superpuestas de *pattern* en
   *string*, como una lista de strings o tuplas. El *string* se
   escanea de izquierda a derecha y las coincidencias se retornan en
   el orden en que se encuentran. Las coincidencias vacías se incluyen
   en el resultado.

   El resultado depende del número de grupos detectados en el patrón.
   Si no hay grupos, retorna una lista de strings que coincidan con el
   patrón completo. Si existe exactamente un grupo, retorna una lista
   de strings que coincidan con ese grupo. Si hay varios grupos
   presentes, retorna una lista de tuplas de strings que coinciden con
   los grupos. Los grupos que no son detectados no afectan la forma
   del resultado.

   >>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
   ['foot', 'fell', 'fastest']
   >>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
   [('width', '20'), ('height', '10')]

   Distinto en la versión 3.7: Las coincidencias no vacías ahora
   pueden empezar justo después de una coincidencia vacía anterior.

re.finditer(pattern, string, flags=0)

   Return an *iterator* yielding "Match" objects over all non-
   overlapping matches for the RE *pattern* in *string*.  The *string*
   is scanned left-to-right, and matches are returned in the order
   found.  Empty matches are included in the result.

   Distinto en la versión 3.7: Las coincidencias no vacías ahora
   pueden empezar justo después de una coincidencia vacía anterior.

re.sub(pattern, repl, string, count=0, flags=0)

   Retorna la cadena obtenida reemplazando las ocurrencias no
   superpuestas del *pattern* ("patrón") en la *string* ("cadena") por
   el reemplazo de *repl*.  Si el patrón no se encuentra, se retorna
   *string* sin cambios.  *repl* puede ser una cadena o una función;
   si es una cadena, cualquier barra inversa escapada en ella es
   procesada.  Es decir, "\n" se convierte en un carácter de una sola
   línea nueva, "\r" se convierte en un retorno de carro, y así
   sucesivamente.  Los escapes desconocidos de las letras ASCII se
   reservan para un uso futuro y se tratan como errores.  Otros
   escapes desconocidos como "\&" no se utilizan. Las referencias
   inversas, como "\6", se reemplazan por la subcadena que corresponde
   al grupo 6 del patrón. Por ejemplo:

      >>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
      ...        r'static PyObject*\npy_\1(void)\n{',
      ...        'def myfunc():')
      'static PyObject*\npy_myfunc(void)\n{'

   If *repl* is a function, it is called for every non-overlapping
   occurrence of *pattern*.  The function takes a single "Match"
   argument, and returns the replacement string.  For example:

      >>> def dashrepl(matchobj):
      ...     if matchobj.group(0) == '-': return ' '
      ...     else: return '-'
      >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')
      'pro--gram files'
      >>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
      'Baked Beans & Spam'

   The pattern may be a string or a "Pattern".

   El argumento opcional *count* ("recuento") es el número máximo de
   ocurrencias de patrones a ser reemplazados; *count* debe ser un
   número entero no negativo.  Si se omite o es cero, todas las
   ocurrencias serán reemplazadas. Las coincidencias vacías del patrón
   se reemplazan sólo cuando no están adyacentes a una coincidencia
   vacía anterior, así que "sub('x*', '-', 'abxd')" retorna "'-a-b--
   d-'".

   En los argumentos *repl* de tipo cadena, además de los escapes de
   caracteres y las referencias inversas descritas anteriormente,
   "\g<name>" usará la subcadena coincidente con el grupo llamado
   "name", como se define en la sintaxis "(?P<name>...)". "\g<number>"
   utiliza el número de grupo correspondiente; "\g<2>" es por lo tanto
   equivalente a "\2", pero no es ambiguo en un reemplazo como sucede
   con "\g<2>0".  "\20" se interpretaría como una referencia al grupo
   20, no como una referencia al grupo 2 seguido del carácter literal
   "'0'".  La referencia inversa "\g<0>" sustituye en toda la
   subcadena coincidente con la RE.

   Distinto en la versión 3.1: Se añadió el argumento de los
   indicadores opcionales.

   Distinto en la versión 3.5: Los grupos no coincidentes son
   reemplazados por una cadena vacía.

   Distinto en la versión 3.6: Los escapes desconocidos en el
   *pattern* que consisten en "'\'" y una letra ASCII ahora son
   errores.

   Distinto en la versión 3.7: Los escapes desconocidos en *repl* que
   consisten en "'\'" y una letra ASCII ahora son errores.

   Distinto en la versión 3.7: Las coincidencias vacías para el patrón
   se reemplazan cuando están adyacentes a una coincidencia anterior
   no vacía.

   Obsoleto desde la versión 3.11: Group *id* containing anything
   except ASCII digits. Group *name* containing characters outside the
   ASCII range ("b'\x00'"-"b'\x7f'") in "bytes" replacement strings.

re.subn(pattern, repl, string, count=0, flags=0)

   Realiza la misma operación que "sub()", pero retorna una tupla
   "(new_string, number_of_subs_made)".

   Distinto en la versión 3.1: Se añadió el argumento de los
   indicadores opcionales.

   Distinto en la versión 3.5: Los grupos no coincidentes son
   reemplazados por una cadena vacía.

re.escape(pattern)

   Caracteres de escape especiales en *pattern* (" patrón"). Esto es
   útil si quieres hacer coincidir una cadena literal arbitraria que
   puede tener metacaracteres de expresión regular en ella.  Por
   ejemplo:

      >>> print(re.escape('https://www.python.org'))
      https://www\.python\.org

      >>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"
      >>> print('[%s]+' % re.escape(legal_chars))
      [abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+

      >>> operators = ['+', '-', '*', '/', '**']
      >>> print('|'.join(map(re.escape, sorted(operators, reverse=True))))
      /|\-|\+|\*\*|\*

   Esta función no debe usarse para la cadena de reemplazo en "sub()"
   y "subn()", sólo deben escaparse las barras inversas.  Por ejemplo:

      >>> digits_re = r'\d+'
      >>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings'
      >>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample))
      /usr/sbin/sendmail - \d+ errors, \d+ warnings

   Distinto en la versión 3.3: El carácter de "'_'" ya no se escapa.

   Distinto en la versión 3.7: Sólo se escapan los caracteres que
   pueden tener un significado especial en una expresión regular. Como
   resultado, "'!'", "'"'", "'%'", ""'"", "','", "'/'", "':'", "';'",
   "'<'", "'='", "'>'", "'@'" y ""`"" ya no se escapan.

re.purge()

   Despeja la caché de expresión regular.


Excepciones
-----------

exception re.error(msg, pattern=None, pos=None)

   Excepción señalada cuando una cadena enviada a una de las funciones
   descritas aquí no es una expresión regular válida (por ejemplo,
   podría contener paréntesis no coincidentes) o cuando se produce
   algún otro error durante la compilación o la coincidencia.  Nunca
   es un error si una cadena no contiene ninguna coincidencia para un
   patrón.  La instancia de error tiene los siguientes atributos
   adicionales:

   msg

      El mensaje de error sin formato.

   pattern

      El patrón de expresión regular.

   pos

      El índice en *pattern* ("patrón") donde la compilación falló
      (puede ser "None").

   lineno

      La línea correspondiente a *pos* (puede ser "None").

   colno

      La columna correspondiente a *pos* (puede ser "None").

   Distinto en la versión 3.5: Se añadieron atributos adicionales.


Objetos expresión regular
=========================

class re.Pattern

   Compiled regular expression object returned by "re.compile()".

   Distinto en la versión 3.9: "re.Pattern" supports "[]" to indicate
   a Unicode (str) or bytes pattern. See Tipo Alias Genérico.

Pattern.search(string[, pos[, endpos]])

   Scan through *string* looking for the first location where this
   regular expression produces a match, and return a corresponding
   "Match". Return "None" if no position in the string matches the
   pattern; note that this is different from finding a zero-length
   match at some point in the string.

   El segundo parámetro opcional *pos* proporciona un índice en la
   cadena donde la búsqueda debe comenzar; por defecto es "0".  Esto
   no es completamente equivalente a dividir la cadena; el patrón de
   carácter "'^'" coincide en el inicio real de la cadena y en las
   posiciones justo después de una nueva línea, pero no necesariamente
   en el índice donde la búsqueda va a comenzar.

   El parámetro opcional *endpos* limita hasta dónde se buscará la
   cadena; será como si la cadena fuera de *endpos* caracteres de
   largo, por lo que sólo se buscará una coincidencia entre los
   caracteres de *pos* a "endpos - 1".  Si *endpos* es menor que
   *pos*, no se encontrará ninguna coincidencia; de lo contrario, si
   *rx* es un objeto de expresión regular compilado,
   "rx.search(string, 0, 50)" es equivalente a "rx.search(string[:50],
   0)".

      >>> pattern = re.compile("d")
      >>> pattern.search("dog")     # Match at index 0
      <re.Match object; span=(0, 1), match='d'>
      >>> pattern.search("dog", 1)  # No match; search doesn't include the "d"

Pattern.match(string[, pos[, endpos]])

   If zero or more characters at the *beginning* of *string* match
   this regular expression, return a corresponding "Match". Return
   "None" if the string does not match the pattern; note that this is
   different from a zero-length match.

   Los parámetros opcionales *pos* y *endpos* tienen el mismo
   significado que para el método "search()".

      >>> pattern = re.compile("o")
      >>> pattern.match("dog")      # No match as "o" is not at the start of "dog".
      >>> pattern.match("dog", 1)   # Match as "o" is the 2nd character of "dog".
      <re.Match object; span=(1, 2), match='o'>

   Si se quiere encontrar una coincidencia en cualquier lugar de
   *string*, utilizar "search()" en su lugar (ver también search() vs.
   match()).

Pattern.fullmatch(string[, pos[, endpos]])

   If the whole *string* matches this regular expression, return a
   corresponding "Match".  Return "None" if the string does not match
   the pattern; note that this is different from a zero-length match.

   Los parámetros opcionales *pos* y *endpos* tienen el mismo
   significado que para el método "search()".

      >>> pattern = re.compile("o[gh]")
      >>> pattern.fullmatch("dog")      # No match as "o" is not at the start of "dog".
      >>> pattern.fullmatch("ogre")     # No match as not the full string matches.
      >>> pattern.fullmatch("doggie", 1, 3)   # Matches within given limits.
      <re.Match object; span=(1, 3), match='og'>

   Nuevo en la versión 3.4.

Pattern.split(string, maxsplit=0)

   Idéntico a la función "split()", usando el patrón compilado.

Pattern.findall(string[, pos[, endpos]])

   Similar a la función "findall()", usando el patrón compilado, pero
   también acepta parámetros opcionales *pos* y *endpos* que limitan
   la región de búsqueda como para "search()".

Pattern.finditer(string[, pos[, endpos]])

   Similar a la función "finditer()", usando el patrón compilado, pero
   también acepta parámetros opcionales *pos* y *endpos* que limitan
   la región de búsqueda como para "search()".

Pattern.sub(repl, string, count=0)

   Idéntico a la función "sub()", usando el patrón compilado.

Pattern.subn(repl, string, count=0)

   Idéntico a la función "subn()", usando el patrón compilado.

Pattern.flags

   The regex matching flags.  This is a combination of the flags given
   to "compile()", any "(?...)" inline flags in the pattern, and
   implicit flags such as "UNICODE" if the pattern is a Unicode
   string.

Pattern.groups

   El número de grupos de captura en el patrón.

Pattern.groupindex

   Un diccionario que mapea cualquier nombre de grupo simbólico
   definido por "(?P<id>)" para agrupar números.  El diccionario está
   vacío si no se utilizaron grupos simbólicos en el patrón.

Pattern.pattern

   La cadena de patrones a partir de la cual el objeto de patrón fue
   compilado.

Distinto en la versión 3.7: Se añadió el soporte de "copy.copy()" y
"copy.deepcopy()".  Los objetos expresión regular compilados se
consideran atómicos.


Objetos de coincidencia
=======================

Los objetos de coincidencia siempre tienen un valor booleano de "True"
("Verdadero"). Ya que "match()" y "search()" retornan "None" cuando no
hay coincidencia. Se puede probar si hubo una coincidencia con una
simple declaración "if":

   match = re.search(pattern, string)
   if match:
       process(match)

class re.Match

   Match object returned by successful "match"es and "search"es.

   Distinto en la versión 3.9: "re.Match" supports "[]" to indicate a
   Unicode (str) or bytes match. See Tipo Alias Genérico.

Match.expand(template)

   Return the string obtained by doing backslash substitution on the
   template string *template*, as done by the "sub()" method. Escapes
   such as "\n" are converted to the appropriate characters, and
   numeric backreferences ("\1", "\2") and named backreferences
   ("\g<1>", "\g<name>") are replaced by the contents of the
   corresponding group. The backreference "\g<0>" will be replaced by
   the entire match.

   Distinto en la versión 3.5: Los grupos no coincidentes son
   reemplazados por una cadena vacía.

Match.group([group1, ...])

   Retorna uno o más subgrupos de la coincidencia.  Si hay un solo
   argumento, el resultado es una sola cadena; si hay múltiples
   argumentos, el resultado es una tupla con un elemento por
   argumento. Sin argumentos, *group1* tiene un valor por defecto de
   cero (se retorna la coincidencia completa). Si un argumento
   *groupN* es cero, el valor de retorno correspondiente es toda la
   cadena coincidente; si está en el rango inclusivo [1..99], es la
   cadena coincidente con el grupo correspondiente entre paréntesis.
   Si un número de grupo es negativo o mayor que el número de grupos
   definidos en el patrón, se produce una excepción "IndexError". Si
   un grupo está contenido en una parte del patrón que no coincidió,
   el resultado correspondiente es "None". Si un grupo está contenido
   en una parte del patrón que coincidió varias veces, se retorna la
   última coincidencia.

      >>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
      >>> m.group(0)       # The entire match
      'Isaac Newton'
      >>> m.group(1)       # The first parenthesized subgroup.
      'Isaac'
      >>> m.group(2)       # The second parenthesized subgroup.
      'Newton'
      >>> m.group(1, 2)    # Multiple arguments give us a tuple.
      ('Isaac', 'Newton')

   Si la expresión regular usa la sintaxis "(?P<name>...)", los
   argumentos *groupN* también pueden ser cadenas que identifican a
   los grupos por su nombre de grupo.  Si un argumento de cadena no se
   usa como nombre de grupo en el patrón, se produce una excepción
   "IndexError".

   Un ejemplo moderadamente complicado:

      >>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
      >>> m.group('first_name')
      'Malcolm'
      >>> m.group('last_name')
      'Reynolds'

   Los grupos nombrados también pueden ser referidos por su índice:

      >>> m.group(1)
      'Malcolm'
      >>> m.group(2)
      'Reynolds'

   Si un grupo coincide varias veces, sólo se puede acceder a la
   última coincidencia:

      >>> m = re.match(r"(..)+", "a1b2c3")  # Matches 3 times.
      >>> m.group(1)                        # Returns only the last match.
      'c3'

Match.__getitem__(g)

   Esto es idéntico a "m.group(g)".  Esto permite un acceso más fácil
   a un grupo individual de una coincidencia:

      >>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
      >>> m[0]       # The entire match
      'Isaac Newton'
      >>> m[1]       # The first parenthesized subgroup.
      'Isaac'
      >>> m[2]       # The second parenthesized subgroup.
      'Newton'

   Los grupos con nombre también son compatibles:

      >>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Isaac Newton")
      >>> m['first_name']
      'Isaac'
      >>> m['last_name']
      'Newton'

   Nuevo en la versión 3.6.

Match.groups(default=None)

   Retorna una tupla que contenga todos los subgrupos de la
   coincidencia, desde 1 hasta tantos grupos como haya en el patrón.
   El argumento *default* ("por defecto") se utiliza para los grupos
   que no participaron en la coincidencia; por defecto es "None".

   Por ejemplo:

      >>> m = re.match(r"(\d+)\.(\d+)", "24.1632")
      >>> m.groups()
      ('24', '1632')

   Si hacemos que el decimal y todo lo que sigue sea opcional, no
   todos los grupos podrían participar en la coincidencia.  Estos
   grupos serán por defecto "None" a menos que se utilice el argumento
   *default*:

      >>> m = re.match(r"(\d+)\.?(\d+)?", "24")
      >>> m.groups()      # Second group defaults to None.
      ('24', None)
      >>> m.groups('0')   # Now, the second group defaults to '0'.
      ('24', '0')

Match.groupdict(default=None)

   Retorna un diccionario que contiene todos los subgrupos *nombrados*
   de la coincidencia, tecleado por el nombre del subgrupo.  El
   argumento *por defecto* se usa para los grupos que no participaron
   en la coincidencia; por defecto es "None".  Por ejemplo:

      >>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
      >>> m.groupdict()
      {'first_name': 'Malcolm', 'last_name': 'Reynolds'}

Match.start([group])
Match.end([group])

   Retorna los índices del comienzo y el final de la subcadena
   coincidiendo con el *group*; el *group* por defecto es cero (es
   decir, toda la subcadena coincidente). Retorna "-1" si *grupo*
   existe pero no ha contribuido a la coincidencia.  Para un objeto
   coincidente *m*, y un grupo *g* que sí contribuyó a la
   coincidencia, la subcadena coincidente con el grupo *g*
   (equivalente a "m.group(g)") es

      m.string[m.start(g):m.end(g)]

   Notar que "m.start(group)" será igual a "m.end(group)" si *group*
   coincidió con una cadena nula.  Por ejemplo, después de "m =
   re.search('b(c?)', 'cba')", "m.start(0)" es 1, "m.end(0)" es 2,
   "m.start(1)" y "m.end(1)" son ambos 2, y "m.start(2)" produce una
   excepción "IndexError".

   Un ejemplo que eliminará *remove_this* ("quita esto") de las
   direcciones de correo electrónico:

      >>> email = "tony@tiremove_thisger.net"
      >>> m = re.search("remove_this", email)
      >>> email[:m.start()] + email[m.end():]
      'tony@tiger.net'

Match.span([group])

   Para una coincidencia *m*, retorna la tupla-2 "(m.inicio(grupo),
   m.fin(grupo))". Notar que si *group* no contribuyó a la
   coincidencia, esto es "(-1, -1)". *group* por se convierte a cero
   para toda la coincidencia.

Match.pos

   El valor de *pos* que fue pasado al método "search()" o "match()"
   de un objeto regex.  Este es el índice de la cadena en la que el
   motor RE comenzó a buscar una coincidencia.

Match.endpos

   El valor de *endpos* que se pasó al método "search()" o "match()"
   de un objeto regex.  Este es el índice de la cadena más allá de la
   cual el motor RE no irá.

Match.lastindex

   El índice entero del último grupo de captura coincidente, o``None``
   si no hay ningún grupo coincidente. Por ejemplo, las expresiones
   "(a)b", "((a)(b))" y "((ab))" tendrán "lastindex == 1" si se
   aplican a la cadena "'ab'", mientras que la expresión "(a)(b)"
   tendrá "lastindex == 2", si se aplica a la misma cadena.

Match.lastgroup

   El nombre del último grupo capturador coincidente, o``None`` si el
   grupo no tenía nombre, o si no había ningún grupo coincidente.

Match.re

   El objeto de expresión regular cuyo método "match()" o "search()"
   produce esta instancia de coincidencia.

Match.string

   La cadena pasada a "match()" o "search()".

Distinto en la versión 3.7: Se añadió el soporte de "copy.copy()" y
"copy.deepcopy()".  Los objetos de coincidencia se consideran
atómicos.


Ejemplos de expresiones regulares
=================================


Buscando un par
---------------

En este ejemplo, se utilizará la siguiente función de ayuda para
mostrar los objetos de coincidencia con un poco más de elegancia:

   def displaymatch(match):
       if match is None:
           return None
       return '<Match: %r, groups=%r>' % (match.group(), match.groups())

Supongamos que se está escribiendo un programa de póquer en el que la
mano de un jugador se representa como una cadena de 5 caracteres en la
que cada carácter representa una carta, "a" para el as, "k" para el
rey, "q" para la reina, "j" para la jota, "t" para el 10, y del " 2"
al "9" representando la carta con ese valor.

Para ver si una cadena dada es una mano válida, se podría hacer lo
siguiente:

   >>> valid = re.compile(r"^[a2-9tjqk]{5}$")
   >>> displaymatch(valid.match("akt5q"))  # Valid.
   "<Match: 'akt5q', groups=()>"
   >>> displaymatch(valid.match("akt5e"))  # Invalid.
   >>> displaymatch(valid.match("akt"))    # Invalid.
   >>> displaymatch(valid.match("727ak"))  # Valid.
   "<Match: '727ak', groups=()>"

Esa última mano, ""727ak"", contenía un par, o dos de las mismas
cartas de valor. Para igualar esto con una expresión regular, se
podrían usar referencias inversas como tales:

   >>> pair = re.compile(r".*(.).*\1")
   >>> displaymatch(pair.match("717ak"))     # Pair of 7s.
   "<Match: '717', groups=('7',)>"
   >>> displaymatch(pair.match("718ak"))     # No pairs.
   >>> displaymatch(pair.match("354aa"))     # Pair of aces.
   "<Match: '354aa', groups=('a',)>"

Para averiguar en qué carta consiste el par, se podría utilizar el
método "group()" del objeto de coincidencia de la siguiente manera:

   >>> pair = re.compile(r".*(.).*\1")
   >>> pair.match("717ak").group(1)
   '7'

   # Error because re.match() returns None, which doesn't have a group() method:
   >>> pair.match("718ak").group(1)
   Traceback (most recent call last):
     File "<pyshell#23>", line 1, in <module>
       re.match(r".*(.).*\1", "718ak").group(1)
   AttributeError: 'NoneType' object has no attribute 'group'

   >>> pair.match("354aa").group(1)
   'a'


Simular scanf()
---------------

Python does not currently have an equivalent to "scanf()".  Regular
expressions are generally more powerful, though also more verbose,
than "scanf()" format strings.  The table below offers some more-or-
less equivalent mappings between "scanf()" format tokens and regular
expressions.

+----------------------------------+-----------------------------------------------+
| "scanf()" Token                  | Expresión regular                             |
|==================================|===============================================|
| "%c"                             | "."                                           |
+----------------------------------+-----------------------------------------------+
| "%5c"                            | ".{5}"                                        |
+----------------------------------+-----------------------------------------------+
| "%d"                             | "[-+]?\d+"                                    |
+----------------------------------+-----------------------------------------------+
| "%e", "%E", "%f", "%g"           | "[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?"     |
+----------------------------------+-----------------------------------------------+
| "%i"                             | "[-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)"         |
+----------------------------------+-----------------------------------------------+
| "%o"                             | "[-+]?[0-7]+"                                 |
+----------------------------------+-----------------------------------------------+
| "%s"                             | "\S+"                                         |
+----------------------------------+-----------------------------------------------+
| "%u"                             | "\d+"                                         |
+----------------------------------+-----------------------------------------------+
| "%x", "%X"                       | "[-+]?(0[xX])?[\dA-Fa-f]+"                    |
+----------------------------------+-----------------------------------------------+

Para extraer el nombre de archivo y los números de una cadena como

   /usr/sbin/sendmail - 0 errors, 4 warnings

you would use a "scanf()" format like

   %s - %d errors, %d warnings

La expresión regular equivalente sería

   (\S+) - (\d+) errors, (\d+) warnings


search() vs. match()
--------------------

Python offers different primitive operations based on regular
expressions:

* "re.match()" checks for a match only at the beginning of the string

* "re.search()" checks for a match anywhere in the string (this is
  what Perl does by default)

* "re.fullmatch()" checks for entire string to be a match

Por ejemplo:

   >>> re.match("c", "abcdef")    # No match
   >>> re.search("c", "abcdef")   # Match
   <re.Match object; span=(2, 3), match='c'>
   >>> re.fullmatch("p.*n", "python") # Match
   <re.Match object; span=(0, 6), match='python'>
   >>> re.fullmatch("r.*n", "python") # No match

Las expresiones regulares que comienzan con "'^'" pueden ser usadas
con "search()" para restringir la coincidencia al principio de la
cadena:

   >>> re.match("c", "abcdef")    # No match
   >>> re.search("^c", "abcdef")  # No match
   >>> re.search("^a", "abcdef")  # Match
   <re.Match object; span=(0, 1), match='a'>

Notar, sin embargo, que en el modo "MULTILINE" "match()" sólo coincide
al principio de la cadena, mientras que usando "search()" con una
expresión regular que comienza con "'^'" coincidirá al principio de
cada línea.

   >>> re.match("X", "A\nB\nX", re.MULTILINE)  # No match
   >>> re.search("^X", "A\nB\nX", re.MULTILINE)  # Match
   <re.Match object; span=(4, 5), match='X'>


Haciendo una guía telefónica
----------------------------

"split()" divide una cadena en una lista delimitada por el patrón
recibido.  El método es muy útil para convertir datos textuales en
estructuras de datos que pueden ser fácilmente leídas y modificadas
por Python, como se demuestra en el siguiente ejemplo en el que se
crea una guía telefónica.

Primero, aquí está la información.  Normalmente puede venir de un
archivo, aquí se usa la sintaxis de cadena de triple comilla

   >>> text = """Ross McFluff: 834.345.1254 155 Elm Street
   ...
   ... Ronald Heathmore: 892.345.3428 436 Finley Avenue
   ... Frank Burger: 925.541.7625 662 South Dogwood Way
   ...
   ...
   ... Heather Albrecht: 548.326.4584 919 Park Place"""

Las entradas (*entries*) están separadas por una o más líneas nuevas.
Ahora se convierte la cadena en una lista en la que cada línea no
vacía tiene su propia entrada:

   >>> entries = re.split("\n+", text)
   >>> entries
   ['Ross McFluff: 834.345.1254 155 Elm Street',
   'Ronald Heathmore: 892.345.3428 436 Finley Avenue',
   'Frank Burger: 925.541.7625 662 South Dogwood Way',
   'Heather Albrecht: 548.326.4584 919 Park Place']

Finalmente, se divide cada entrada en una lista con nombre, apellido,
número de teléfono y dirección.  Se utiliza el parámetro "maxsplit"
(división máxima) de "split()" porque la dirección tiene espacios
dentro del patrón de división:

   >>> [re.split(":? ", entry, 3) for entry in entries]
   [['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],
   ['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],
   ['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],
   ['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]

El patrón ":?" coincide con los dos puntos después del apellido, de
manera que no aparezca en la lista de resultados.  Con "maxsplit" de
"4", se podría separar el número de casa del nombre de la calle:

   >>> [re.split(":? ", entry, 4) for entry in entries]
   [['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],
   ['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],
   ['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],
   ['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]


Mungear texto
-------------

"sub()" reemplaza cada ocurrencia de un patrón con una cadena o el
resultado de una función.  Este ejemplo demuestra el uso de "sub()"
con una función para "mungear" (*munge*) el texto, o aleatorizar el
orden de todos los caracteres en cada palabra de una frase excepto el
primer y último carácter:

   >>> def repl(m):
   ...     inner_word = list(m.group(2))
   ...     random.shuffle(inner_word)
   ...     return m.group(1) + "".join(inner_word) + m.group(3)
   >>> text = "Professor Abdolmalek, please report your absences promptly."
   >>> re.sub(r"(\w)(\w+)(\w)", repl, text)
   'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'
   >>> re.sub(r"(\w)(\w+)(\w)", repl, text)
   'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'


Encontrar todos los adverbios
-----------------------------

"findall()" coincide con *todas* las ocurrencias de un patrón, no sólo
con la primera, como lo hace "search()".  Por ejemplo, si un escritor
quisiera encontrar todos los adverbios en algún texto, podría usar
"findall()" de la siguiente manera:

   >>> text = "He was carefully disguised but captured quickly by police."
   >>> re.findall(r"\w+ly\b", text)
   ['carefully', 'quickly']


Encontrar todos los adverbios y sus posiciones
----------------------------------------------

If one wants more information about all matches of a pattern than the
matched text, "finditer()" is useful as it provides "Match" objects
instead of strings.  Continuing with the previous example, if a writer
wanted to find all of the adverbs *and their positions* in some text,
they would use "finditer()" in the following manner:

   >>> text = "He was carefully disguised but captured quickly by police."
   >>> for m in re.finditer(r"\w+ly\b", text):
   ...     print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
   07-16: carefully
   40-47: quickly


Notación de cadena *raw*
------------------------

La notación de cadena *raw* ("r "text"") permite escribir expresiones
regulares razonables.  Sin ella, para "escapar" cada barra inversa
("'\'") en una expresión regular tendría que ser precedida por otra.
Por ejemplo, las dos siguientes líneas de código son funcionalmente
idénticas:

   >>> re.match(r"\W(.)\1\W", " ff ")
   <re.Match object; span=(0, 4), match=' ff '>
   >>> re.match("\\W(.)\\1\\W", " ff ")
   <re.Match object; span=(0, 4), match=' ff '>

Cuando uno quiere igualar una barra inversa literal, debe escaparse en
la expresión regular.  Con la notación de cadena *raw*, esto significa
"r"\\"".  Sin la notación de cadena, uno debe usar ""\\\\"", haciendo
que las siguientes líneas de código sean funcionalmente idénticas:

   >>> re.match(r"\\", r"\\")
   <re.Match object; span=(0, 1), match='\\'>
   >>> re.match("\\\\", r"\\")
   <re.Match object; span=(0, 1), match='\\'>


Escribir un Tokenizador
-----------------------

Un tokenizador o analizador léxico analiza una cadena para categorizar
grupos de caracteres.  Este es un primer paso útil para escribir un
compilador o intérprete.

Las categorías de texto se especifican con expresiones regulares.  La
técnica consiste en combinarlas en una única expresión regular maestra
y en hacer un bucle sobre las sucesivas coincidencias:

   from typing import NamedTuple
   import re

   class Token(NamedTuple):
       type: str
       value: str
       line: int
       column: int

   def tokenize(code):
       keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
       token_specification = [
           ('NUMBER',   r'\d+(\.\d*)?'),  # Integer or decimal number
           ('ASSIGN',   r':='),           # Assignment operator
           ('END',      r';'),            # Statement terminator
           ('ID',       r'[A-Za-z]+'),    # Identifiers
           ('OP',       r'[+\-*/]'),      # Arithmetic operators
           ('NEWLINE',  r'\n'),           # Line endings
           ('SKIP',     r'[ \t]+'),       # Skip over spaces and tabs
           ('MISMATCH', r'.'),            # Any other character
       ]
       tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
       line_num = 1
       line_start = 0
       for mo in re.finditer(tok_regex, code):
           kind = mo.lastgroup
           value = mo.group()
           column = mo.start() - line_start
           if kind == 'NUMBER':
               value = float(value) if '.' in value else int(value)
           elif kind == 'ID' and value in keywords:
               kind = value
           elif kind == 'NEWLINE':
               line_start = mo.end()
               line_num += 1
               continue
           elif kind == 'SKIP':
               continue
           elif kind == 'MISMATCH':
               raise RuntimeError(f'{value!r} unexpected on line {line_num}')
           yield Token(kind, value, line_num, column)

   statements = '''
       IF quantity THEN
           total := total + price * quantity;
           tax := price * 0.05;
       ENDIF;
   '''

   for token in tokenize(statements):
       print(token)

El tokenizador produce el siguiente resultado:

   Token(type='IF', value='IF', line=2, column=4)
   Token(type='ID', value='quantity', line=2, column=7)
   Token(type='THEN', value='THEN', line=2, column=16)
   Token(type='ID', value='total', line=3, column=8)
   Token(type='ASSIGN', value=':=', line=3, column=14)
   Token(type='ID', value='total', line=3, column=17)
   Token(type='OP', value='+', line=3, column=23)
   Token(type='ID', value='price', line=3, column=25)
   Token(type='OP', value='*', line=3, column=31)
   Token(type='ID', value='quantity', line=3, column=33)
   Token(type='END', value=';', line=3, column=41)
   Token(type='ID', value='tax', line=4, column=8)
   Token(type='ASSIGN', value=':=', line=4, column=12)
   Token(type='ID', value='price', line=4, column=15)
   Token(type='OP', value='*', line=4, column=21)
   Token(type='NUMBER', value=0.05, line=4, column=23)
   Token(type='END', value=';', line=4, column=27)
   Token(type='ENDIF', value='ENDIF', line=5, column=4)
   Token(type='END', value=';', line=5, column=9)

[Frie09] Friedl, Jeffrey. *Mastering Regular Expressions*. 3a ed.,
         O'Reilly Media, 2009. La tercera edición del libro ya no
         abarca a Python en absoluto, pero la primera edición cubría
         la escritura de buenos patrones de expresiones regulares con
         gran detalle.
