Espacios de nombres
Variantes
Acciones

Gramática modificada de expresiones regulares de ECMAScript

De cppreference.com
< cpp‎ | regex
 
 
Biblioteca de expresiones regulares
Clases
(C++11)
Algoritmos
Iteradores
Excepciones
Rasgos
Constantes
(C++11)
Gramática de las expresiones regulares
ECMAScript-262 modificado
(C++11)
 
 

Esta página describe la gramática de las expresiones regulares que se usa cuando std::basic_regex se construye con syntax_option_type establecido en ECMAScript (el valor por defecto). Véase syntax_option_type para el apoyo de otras gramáticas de expresiones regulares.

La gramática de las expresiones regulares ECMAScript 3 en C++ es la gramática ECMA-262 con modificaciones marcadas con (solo C++) a continuación.

Contenido

[editar] Descripción general

La gramática modificada de expresiones regulares es en su mayoría la gramática ECMAScript RegExp con una expansión de tipo POSIX en configuraciones regionales bajo ClassAtom. Se hacen algunas aclaraciones sobre las verificaciones de igualdad y el análisis de números. Para muchos de los ejemplos aquí, puedes probar este equivalente en la consola de tu navegador:

function match(s, re) { return s.match(new RegExp(re)); }

Las "referencias normativas" en el estándar especifican ECMAScript 3. Aquí enlazamos a la especificación ECMAScript 5.1 porque es una versión con solo cambios menores de ECMAScript 3, y también tiene una versión HTML. Véase la Guía MDN sobre JavaScript RegExp para obtener una descripción general de las características del dialecto.

[editar] Alternancias

Un patrón de expresión regular es una secuencia de una o más Alternancias, separadas por el operador de disyunción | (en otras palabras, el operador de disyunción tiene la precedencia más baja).

Patrón ::

Disyunción

Disyunción ::

Alternancia
Alternancia | Disyunción

El patrón primero intenta saltarse la Disyunción y hacer coincidir la Alternancia izquierda seguida por el resto de la expresión regular (después de la Disyunción).

Si falla, intenta saltarse la Alternancia de la izquierda y hacer coincidir la Disyunción de la derecha (seguida del resto de la expresión regular).

Si la Alternancia de la izquierda, la Disyunción de la derecha y el resto de la expresión regular tienen puntos de elección, se prueban todas las opciones del resto de la expresión antes de pasar a la siguiente opción en la Alternancia izquierda. Si se agotan las opciones de la Alternancia de la izquierda, se intenta la Disyunción de la derecha en lugar de la Alternancia de la izquierda.

Cualquier paréntesis de captura dentro de una Alternancia omitida produce subcoincidencias vacías.

#include <iostream>
#include <string>
#include <regex>
 
// Muestra las coincidencias dada una entrada (in) y una expresión regular (re)
void coincidencias(const std::string& in, const std::string& re)
{
    std::smatch m;
    std::regex_search(in, m, std::regex(re));
    if(!m.empty()) {
        std::cout << "entrada=[" << in << "], regex=[" << re << "]\n  "
                     "prefijo=[" << m.prefix() << "]\n  smatch: ";
        for(std::size_t n = 0; n < m.size(); ++n)
            std::cout << "m[" << n << "]=[" << m[n] << "] ";
        std::cout << "\n  sufijo=[" << m.suffix() << "]\n";
    } else {
        std::cout << "entrada=[" << in << "], regex=[" << re << "]: NO HAY COINCIDENCIA(S)\n";
    }
}
 
int main()
{
    coincidencias("abcdef", "abc|def");
    coincidencias("abc", "ab|abc"); // Alternancia de la izquierda se coincide primero
 
    // Coincidencia de la entrada frente a la Alternancia de la izquierda (a)
    // seguida del resto de la expresión regular (c|bc) tiene éxito,
    // lo que resulta en m[1]="a" y m[4]="bc".
    // Las Alternancias omitidas (ab) y (c) dejan sus subsecuencias
    // m[3] y m[5] vacías.
    coincidencias("abc", "((a)|(ab))((c)|(bc))");
}

Salida:

entrada=[abcdef], regex=[abc|def]
  prefijo=[]
  smatch: m[0]=[abc]
  sufijo=[def]
entrada=[abc], regex=[ab|abc]
  prefijo=[]
  smatch: m[0]=[ab]
  sufijo=[c]
entrada=[abc], regex=[((a)|(ab))((c)|(bc))]
  prefijo=[]
  smatch: m[0]=[abc] m[1]=[a] m[2]=[a] m[3]=[] m[4]=[bc] m[5]=[] m[6]=[bc]
  sufijo=[]

[editar] Términos

Cada Alternancia está o bien vacía o es una secuencia de Términos (sin separadores entre los Términos.

Alternancia ::

[vacía]
Alternancia Término

Una Alternancia vacía siempre coincide y no consume ninguna entrada.

Los Términos consecutivos tratan de coincidir simultáneamente porciones consecutivas de la entrada.

Si la Alternancia de la izquierda, el Término de la derecha, y el resto de la expresión regular tienen puntos de elección, todas las opciones en el resto de la expresión se prueban antes de pasar a la siguiente opción en el Término de la derecha, y todas las opciones en el Término de la derecha se intentan antes de pasar a la siguiente opción de Alternancia de la izquierda.

#include <iostream>
#include <string>
#include <regex>
 
// Muestra las coincidencias dada una entrada (in) y una expresión regular (re)
void coincidencias(const std::string& in, const std::string& re)
{
    std::smatch m;
    std::regex_search(in, m, std::regex(re));
    if(!m.empty()) {
        std::cout << "entrada=[" << in << "], regex=[" << re << "]\n  "
                     "prefijo=[" << m.prefix() << "]\n  smatch: ";
        for(std::size_t n = 0; n < m.size(); ++n)
            std::cout << "m[" << n << "]=[" << m[n] << "] ";
        std::cout << "\n  sufijo=[" << m.suffix() << "]\n";
    } else {
        std::cout << "entrada=[" << in << "], regex=[" << re << "]: NO HAY COINCIDENCIA(S)\n";
    }
}
 
int main()
{
    coincidencias("abcdef", "");      // Expresión regular vacía
                                     // es una Alternancia simple vacía
    coincidencias("abc", "abc|"); // Alternancia de la izquierda se coincide primero
    coincidencias("abc", "|abc"); // Alternancia de la izquierda, dejando a
                                     // sin coincidir
}

Salida:

entrada=[abcdef], regex=[]
  prefijo=[]
  smatch: m[0]=[]
  sufijo=[abcdef]
entrada=[abc], regex=[abc|]
  prefijo=[]
  smatch: m[0]=[abc]
  sufijo=[]
entrada=[abc], regex=[|abc]
  prefijo=[]
  smatch: m[0]=[]
  sufijo=[abc]

[editar] Cuantificadores

  • Cada Término es o bien una Aserción (véase a continuación), o un Átomo (véase a continuación), o un Átomo inmediatamente seguido de un Cuantificador

Término ::

Aserción
Átomo
Átomo Cuantificador

Cada Cuantificador es o bien un cuantificador voraz (que consiste de solo un PrefijoDeCuantificador) o un cuantificador no voraz (que consiste de un PrefijoDeCuantificador seguido de un cierre de signo de interrogación ?).

Cuantificador::

PrefijoDeCuantificador
PrefijoDeCuantificador ?

Cada PrefijoDeCuantificador determina dos números: el número mínimo de repeticiones y el número máximo de repeticiones, de la manera siguiente:

PrefijoDeCuantificador Mínimo Máximo
* Cero. Infinito.
+ Uno. Infinito.
? Cero. Uno.
{ DígitosDecimales } Valor de DígitosDecimales. Valor de DígitosDecimales.
{ D��gitosDecimales , } Valor de DígitosDecimales. Infinito.
{ DígitosDecimales , DígitosDecimales } Valor de DígitosDecimales antes de la coma. Valor de DígitosDecimales después de la coma.

Los valores de los DígitosDecimales individuales se obtienen llamando a std::regex_traits::value(solo C++) en cada uno de los dígitos.

Un Átomo seguido de un Cuantificador se repite el número de veces especificado por el Cuantificador. Un Cuantificador puede ser no voraz, en cuyo caso el patrón del Átomo se repite tan pocas veces como sea posible sin dejar de coincidir con el resto de la expresión regular, o puede ser voraz, en cuyo caso el patrón del Átomo se repite tantas veces como sea posible sin dejar de coincidir con el resto de la expresión regular

El patrón del Átomo es lo que se repite, no la entrada que coincide, por lo que diferentes repeticiones del Átomo pueden coincidir con diferentes subcadenas de entrada.

Si el Átomo y el resto de la expresión regular tienen puntos de elección, el Átomo se coincide primero tantas veces (o tan pocas, si es no voraz) como sea posible. Todas las opciones del resto de la expresión regular se prueban antes de pasar a la siguiente opción en la última repetición del Átomo. Todas las opciones en la última (n-ésima) repetición del Átomo se prueban antes de pasar a la siguiente opción en la penúltima (n – 1) repetición del Átomo; en ese momento puede resultar que ahora sean posibles más o menos repeticiones de Átomo; estos se agotan (nuevamente, comenzando con tan pocos o tantos como sea posible) antes de pasar a la siguiente opción en la (n-1) repetición del Átomo y así sucesivamente.

Las capturas de los Átomos se borran cada vez que se repite (véase el ejemplo "(z)((a+)?(b+)?(c))*" a continuación).

#include <iostream>
#include <string>
#include <regex>
 
// Muestra las coincidencias dada una entrada (in) y una expresión regular (re)
void coincidencias(const std::string& in, const std::string& re)
{
    std::smatch m;
    std::regex_search(in, m, std::regex(re));
    if(!m.empty()) {
        std::cout << "entrada=[" << in << "], regex=[" << re << "]\n  "
                     "prefijo=[" << m.prefix() << "]\n  smatch: ";
        for(std::size_t n = 0; n < m.size(); ++n)
            std::cout << "m[" << n << "]=[" << m[n] << "] ";
        std::cout << "\n  sufijo=[" << m.suffix() << "]\n";
    } else {
        std::cout << "entrada=[" << in << "], regex=[" << re << "]: NO HAY COINCIDENCIA(S)\n";
    }
}
 
int main()
{
    // coincidencia voraz, repite [a-z] 4 veces
    coincidencias("abcdefghi", "a[a-z]{2,4}");
    // coincidencia no voraz, repite [a-z] 2 veces
    coincidencias("abcdefghi", "a[a-z]{2,4}?");
 
    // El orden de los puntos de elección para los cuantificadores
    // da como resultado una coincidencia con dos repeticiones,
    // primero con la subcadena "aa", en segundo lugar con la 
    // subcadena "ba", dejando "ac" sin coincidir
    // ("ba" aparece en la cláusula de captura m[1])
    coincidencias("aabaac", "(aa|aabaac|ba|b|c)*");
 
    // El orden de los puntos de elección para los cuantificadores
    // hace que esta expresión regular calcule el mayor común divisor
    // entre 10 y 15 (la respuesta es 5, y rellena m[1] con "aaaaa")
    coincidencias("aaaaaaaaaa,aaaaaaaaaaaaaaa", "^(a+)\\1*,\\1+$");
 
    // La subcadena "bbb" aparece en la cláusula de captura m[4]
    // porque se borra cuando la segunda repetición del átomo
    // (a+)?(b+)?(c) coincide con la subcadena matching "ac"
    // NOTA: gcc lo hace mal - no borra correctamente el grupo de
    // captura matches[4] como se requiere por ECMA-262 21.2.2.5.1,
    // y es por esto que incorrectamente captura "bbb" para ese grupo.
    coincidencias("zaacbbbcac", "(z)((a+)?(b+)?(c))*");
}

Salida:

entrada=[abcdefghi], regex=[a[a-z]{2,4}]
  prefijo=[]
  smatch: m[0]=[abcde]
  sufijo=[fghi]
entrada=[abcdefghi], regex=[a[a-z]{2,4}?]
  prefijo=[]
  smatch: m[0]=[abc]
  sufijo=[defghi]
entrada=[aabaac], regex=[(aa|aabaac|ba|b|c)*]
  prefijo=[]
  smatch: m[0]=[aaba] m[1]=[ba]
  sufijo=[ac]
entrada=[aaaaaaaaaa,aaaaaaaaaaaaaaa], regex=[^(a+)\1*,\1+$]
  prefijo=[]
  smatch: m[0]=[aaaaaaaaaa,aaaaaaaaaaaaaaa] m[1]=[aaaaa]
  sufijo=[]
entrada=[zaacbbbcac], regex=[(z)((a+)?(b+)?(c))*]
  prefijo=[]
  smatch: m[0]=[zaacbbbcac] m[1]=[z] m[2]=[ac] m[3]=[a] m[4]=[] m[5]=[c] 
  sufijo=[]

[editar] Aserciones

Una Aserción coincide con las condiciones, en lugar de las subcadenas de la cadena de entrada. Nunca consume ningún carácter de la entrada. Cada Aserción es uno de los siguientes:

Aserción ::

^
$
\ b
\ B
( ? = Disyunción )
( ? ! Disyunción )

La aserción ^ (comienzo de la línea) coincide con

1) La posición que inmediatemente sigue al carácter TerminadorDeLínea (puede que no haya apoyo) (hasta C++17) (esto solo se garantiza si std::regex_constants::multiline(solo C++) está habilitado). (desde C++17)
2) El comienzo de la entrada (a menos que std::regex_constants::match_not_bol(solo C++) esté habilitado).

La aserción $ (fin de línea) matches

1) La posición de un carácter TerminadorDeLínea (puede que no haya apoyo) (hasta C++17)(esto solo se garantiza si std::regex_constants::multiline(solo C++) está habilitado). (desde C++17)
2) El final de la entrada (a menos que std::regex_constants::match_not_eol(solo C++) esté habilitado).

En las dos aserciones anteriores y en el Átomo . a continuación, el TerminadorDeLínea es uno de los siguientes cuatro caracteres: U+000A (\n o salto de línea), U+000D (\r o retorno de carro ), U+2028 (separador de línea), o U+2029 (separador de párrafo).

La aserción \b (límite de palabra) coincide con:

1) El comienzo de una palabra (el carácter actual es una letra, un dígito o un guión bajo, y el carácter anterior no es uno de esos).
2) El final de una palabra (el carácter actual no es una letra, un dígito o un guión bajo, y el carácter anterior es uno de esos).
3) El comienzo de la entrada si el primer carácter es una letra, un dígito o un guión bajo (a menos que std::regex_constants::match_not_bow(solo C++) esté habilitado).
4) El final de la entrada si el primer carácter es una letra, un dígito o un guión bajo (a menos que std::regex_constants::match_not_eow(solo C++) esté habilitado).

La aserción \B (límite de palabra negativo) coincide con todo EXCEPTO lo siguiente:

1) El comienzo de una palabra (el carácter actual es una letra, un dígito o un guión bajo, y el carácter anterior no es uno de esos o no existe).
2) El final de una palabra (el carácter actual no es una letra, un dígito o un guión bajo (o el matcher se encuentra al final de la entrada), y el carácter anterior es uno de esos.

La aserción ( ? = Disyunción ) (anticipación positiva de anchura cero) coincide si la Disyunción coincidiría con la entrada en la posición actual.

La aserción ( ? ! Disyunción ) (anticipación negativa de anchura cero) coincide si la Disyunción NO coincidiría con la entrada en la posición actual.

Para ambas aserciones de Anticipación, al coincidir con la Disyunción, la posición no avanza antes de coincidir con el resto de la expresión regular. Además, si la Disyunción puede coincidir en la posición actual de varias formas, solo se intenta la primera.

ECMAScript prohíbe retroceder a las Disyunciones de anticipación, lo que afecta el comportamiento de las referencias inversas a una anticipación positiva del resto de la expresión regular (véase el ejemplo a continuación). Las referencias inversas a la anticipación negativa del resto de la expresión regular siempre están indefinidas (ya que la Disyunción de anticipación debe fallar).

Nota: Las aserciones de Anticipación se pueden usar para crear un AND lógico entre múltiples expresiones regulares (véase el ejemplo a continuación).

#include <iostream>
#include <string>
#include <regex>
 
// Muestra las coincidencias dada una entrada (in) y una expresión regular (re)
void coincidencias(const std::string& in, const std::string& re)
{
    std::smatch m;
    std::regex_search(in, m, std::regex(re));
    if(!m.empty()) {
        std::cout << "entrada=[" << in << "], regex=[" << re << "]\n  "
                     "prefijo=[" << m.prefix() << "]\n  smatch: ";
        for(std::size_t n = 0; n < m.size(); ++n)
            std::cout << "m[" << n << "]=[" << m[n] << "] ";
        std::cout << "\n  sufijo=[" << m.suffix() << "]\n";
    } else {
        std::cout << "entrada=[" << in << "], regex=[" << re << "]: NO HAY COINCIDENCIA(S)\n";
    }
}
 
int main()
{
    // coincide la a al final de la entrada
    coincidencias("aaa", "a$");
 
    // coincide la o al final de la primera palabra
    coincidencias("moo goo gai pan", "o\\b");
 
    // la anticipación coincide la cadena vacía inmediatamente
    // después de la primera b; esto rellena m[1] con "aaa"
    // aunque m[0] esté vacía
    coincidencias("baaabac", "(?=(a+))");
 
    // ya que se prohíbe las referencias inversas en las
    // anticipaciones, esto coincide aba en vez de aaaba
    coincidencias("baaabac", "(?=(a+))a*b\\1");
 
    // AND lógico mediante anticipación:
    // esta contraseña coincide SI contiene
    // al menos una letra minúscula
    // Y al menos una letra mayúscula
    // Y al menos uno de los signos de puntuación
    // Y al menos tiene 6 caracters de longitud
    coincidencias("abcdef", "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}");
    coincidencias("aB,def", "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}");
}

Salida:

entrada=[aaa], regex=[a$]
  prefijo=[aa]
  smatch: m[0]=[a] 
  sufijo=[]
entrada=[moo goo gai pan], regex=[o\b]
  prefijo=[mo]
  smatch: m[0]=[o] 
  sufijo=[ goo gai pan]
entrada=[baaabac], regex=[(?=(a+))]
  prefijo=[b]
  smatch: m[0]=[] m[1]=[aaa] 
  sufijo=[aaabac]
entrada=[baaabac], regex=[(?=(a+))a*b\1]
  prefijo=[baa]
  smatch: m[0]=[aba] m[1]=[a] 
  sufijo=[c]
entrada=[abcdef], regex=[(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}]: NO HAY COINCIDENCIA(S)
entrada=[aB,def], regex=[(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}]
  prefijo=[]
  smatch: m[0]=[aB,def] 
  sufijo=[]

[editar] Átomos

Un Átomo puede ser uno de los siguientes:

Átomo ::

CarácterDePatrón
.
\ EscapeDeÁtomo
ClaseDeCaracteres
( Disyunción )
( ? : Disyunción )

donde: EscapeDeÁtomo ::

EscapeDecimal
EscapeDeCarácter
EscapeDeClaseDeCaracteres

Distintos tipos de átomos se evalúan de manera distinta.

[editar] Subexpresiones

El Átomo ( Disyunción ) es una subexpresión marcada: ejecuta la Disyunción y almacena la copia de la subcadena de entrada que fue consumida por la Disyunción en el array de subcoincidencias en el índice que corresponde al número de veces que el paréntesis abierto izquierdo ( de subexpresiones marcadas se ha encontrado en toda la expresión regular en este punto.

Además de ser devueltas en los resultados de coincidencias (std::match_results), las subcoincidencias capturadas son accesibles como referencias inversas (\1, \2, ...) y pueden ser referenciadas en las expresiones regulares. Ten en cuenta que std::regex_replace utiliza $ en lugar de \ para las referencias inversas ($1, $2, ...) de la misma manera que String.prototype.replace (ECMA-262, parte 15.5.4.11).

El Átomo ( ? : Disyunción ) (una subexpresión no marcada) simplemente evalúa la Disyunción y no almacena sus resultados en la subcoincidencia. Esto es puramente un agrupamiento léxico.

[editar] Referencias inversas

EscapeDecimal ::

LiteralEnteroDecimal [anticipaciónDígitoDecimal]

Si \ está seguido de un número decimal N cuyo primer dígito no es 0, entonces la secuencia de escape se considera que es una referencia inversa. El valor N se obtiene llamando a std::regex_traits::value(solo C++) en cada uno de los dígitos y combinando sus resultados usando aritmética de base 10. Es un error si N es mayor que el número total de paréntesis de captura izquierda en toda la expresión regular.

Cuando una referencia inversa \N aparece como un Átomo, coincide con la misma subcadena que la que está almacenada actualmente en el N-ésimo elemento del array de subcoincidencias.

El escape decimal \0 NO es una referencia inversa: es un escape de carácter que representa el carácter NUL. No puede estar seguido de un dígito decimal.

Como se indicó anteriormente, ten en cuenta que std::regex_replace utiliza $ en lugar de \ para las referencias inversas ($1, $2, ...).

[editar] Coincidencias de un solo carácter

El Átomo . coincide y consume cualquier carácter de la cadena de entrada excepto el TerminadorDeLínea (U+000D, U+000A, U+2029, o U+2028)

El Átomo CarácterDePatrón, donde CarácterDePatrón es cualquier CarácterFuente EXCEPTO los caracteres ^ $ \ . * + ? ( ) [ ] { } |, coincide y consume un carácter de la entrada si es igual a este CarácterDePatrón.

La igualdad para esta y todas las demás coincidencias de un solo carácter se define de la siguiente manera:

1) Si std::regex_constants::icase está establecido, los caracteres son iguales si los valores de retorno de std::regex_traits::translate_nocase son iguales.(solo C++)
2) De lo contrario, si std::regex_constants::collate está establecido, los caracteres son iguales si los valores de retorno de std::regex_traits::translate son iguales.(solo C++)
3) De lo contrario, los caracteres son iguales si el operador operator== devuelve true.

Cada Átomo que consiste del carácter de escape \ seguido de un EscapeDeCarácter así como el EscapeDecimal especial \0, coincide y consume un carácter de la entrada si es igual al carácter representado por el EscapeDeCarácter. Se reconocen las siguientes secuencias de escape de caracteres:

EscapeDeCarácter ::

EscapeDeControl
c LetraDeControl
SecuenciaDeEscapeHexadecimal
SecuenciaDeEscapeUnicode
IdentidadDeEscape

Aquí, EscapeDeControl es uno de los siguientes cinco caracteres: f n r t v

EscapeDeControl Unidad de Código Nombre
f U+000C Nueva página, salto de página
n U+000A Nueva línea, salto de línea
r U+000D Retorno de carro
t U+0009 Tabulador horizontal
v U+000B Tabulador vertical

LetraDeControl es cualquier letra ASCII en minúsculas o mayúsculas y este escape de carácter coincide con el carácter cuya unidad de código es igual al resto de dividir el valor de la unidad de código de LetraDeControl por 32. Por ejemplo, \cD y \cd ambos coinciden con la unidad de código U+0004 (EOT) porque 'D' es U+0044, y 0x44 % 32 == 4, y 'd' es U+0064 y 0x64 % 32 == 4.

SecuenciaDeEscapeHexadecimal es la letra x seguida de exactamente dos DígitoHexadecimales (donde DígitoHexadecimal es uno de 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F). Este carácter de escape coincide con el carácter cuya unidad de código es igual al valor numérico del número hexadecimal de dos dígitos.

SecuenciaDeEscapeUnicode es la letra u seguida de exactamente cuatro DígitoHexadecimales. Este carácter de escape coincide con el carácter cuya unidad de código es igual al valor numérico de este número hexadecimal de cuatro dígitos. Si el valor no encaja en el argumento de plantilla CharT de este este std::basic_regex, se lanza std::regex_error(solo C++).

IdentidadDeEscape puede ser cualquier carácter no alfanumérico: por ejemplo, otra barra invertida. Coincide con el carácter tal cual.

#include <iostream>
#include <string>
#include <regex>
 
void coincidencias(const std::wstring& in, const std::wstring& re)
{
    std::wsmatch m;
    std::regex_search(in, m, std::wregex(re));
    if(!m.empty()) {
        std::wcout << L"entrada=[" << in << L"], regex=[" << re << L"]\n  "
                      L"prefijo=[" << m.prefix() << L"]\n  wsmatch: ";
        for(std::size_t n = 0; n < m.size(); ++n)
            std::wcout << L"m[" << n << L"]=[" << m[n] << L"] ";
        std::wcout << L"\n  sufijo=[" << m.suffix() << L"]\n";
    } else {
        std::wcout << L"entrada=[" << in << "], regex=[" << re << L"]: NO HAY COINCIDENCIA(S)\n";
    }
}
 
int main()
{
    // La mayoría de los escapes son similares a C++, salvo los
    // metacaracteres. Sin embargo tendrás que hacer un doble escape
    // o usar cadenas sin procesar en las barras.
    coincidencias(L"C++\\", LR"(C\+\+\\)");
 
    // Secuencias de escape y NUL.
    std::wstring s(L"ab\xff\0cd", 5);
    coincidencias(s, L"(\\0|\\u00ff)");
 
    // No se define ninguna coincidencia para Unicode que no sea BMP, porque
    // ECMAScript utiliza átomos UTF-16. Si este emoji banana coincide puede
    // ser dependiente de la plataforma: ¡estas deben ser de cadenas anchas!
    coincidencias(L"\U0001f34c", L"[\\u0000-\\ufffe]+");
}

Posible salida:

entrada=[C++\], regex=[C\+\+\\]
  prefijo=[]
  wsmatch: m[0]=[C++\]
  sufijo=[]
entrada=[ab?c], regex=[(\0{{!}}\u00ff)]
  prefijo=[ab]
  wsmatch: m[0]=[?] m[1]=[?]
  sufijo=[c]
entrada=[?], regex=[[\u0000-\ufffe]+]: NO HAY COINCIDENCIA(S)

[editar] Clases de caracteres

[editar] Clases de caracteres basadas en POSIX