C ++

Conceptos básicos de expresiones regulares en C ++

Conceptos básicos de expresiones regulares en C ++
Considere la siguiente oración entre comillas:

"Aquí está mi hombre."

Esta cadena puede estar dentro de la computadora y el usuario puede querer saber si tiene la palabra "hombre". Si tiene la palabra hombre, es posible que desee cambiar la palabra "hombre" por "mujer"; de modo que la cadena debería leer:

"Aquí está mi mujer."

Hay muchos otros deseos como estos del usuario de la computadora; algunos son complejos. La expresión regular, abreviada, regex, es el tema del manejo de estos problemas por parte de la computadora. C ++ viene con una biblioteca llamada regex. Entonces, un programa en C ++ para manejar expresiones regulares debería comenzar con:

#incluir
#incluir
usando el espacio de nombres std;

Este artículo explica los conceptos básicos de las expresiones regulares en C++.

Contenido del artículo

  • Fundamentos de expresiones regulares
  • Patrón
  • Clases de personajes
  • Coincidencia de espacios en blanco
  • El período (.) en el patrón
  • Repeticiones coincidentes
  • Alternancia coincidente
  • Coincidencia de principio o final
  • Agrupamiento
  • Las constantes regex_constants de icase y multiline
  • Coincidir con todo el objetivo
  • El objeto match_results
  • Posición del partido
  • Buscar y reemplazar
  • Conclusión

Fundamentos de expresiones regulares

Regex

Una cadena como "Aquí está mi hombre."Arriba es la secuencia de destino o cadena de destino o simplemente, destino. "Man", que se buscó, es la expresión regular, o simplemente, regex.

Pareo

Se dice que la coincidencia ocurre cuando se ubica la palabra o frase que se busca. Después de la coincidencia, se puede realizar un reemplazo. Por ejemplo, después de que "hombre" se encuentra arriba, se puede reemplazar por "mujer".

Coincidencia simple

El siguiente programa muestra cómo se relaciona la palabra "hombre".

#incluir
#incluir
usando el espacio de nombres std;
int main ()

regex reg ("hombre");
if (regex_search ("Aquí está mi hombre.", reg))
cout << "matched" << endl;
demás
cout << "not matched" << endl;
return 0;

La función regex_search () devuelve verdadero si hay una coincidencia y devuelve falso si no se produce ninguna coincidencia. Aquí, la función toma dos argumentos: el primero es la cadena de destino y el segundo es el objeto regex. La expresión regular en sí es "hombre", entre comillas dobles. La primera declaración en la función main () forma el objeto regex. Regex es un tipo y reg es el objeto regex. La salida del programa anterior es "coincidente", ya que "man" se ve en la cadena de destino. Si "man" no se hubiera visto en el objetivo, regex_search () habría devuelto falso y la salida habría sido "no coincidente".

La salida del siguiente código "no coincide":

regex reg ("hombre");
if (regex_search ("Aquí está mi creación.", reg))
cout << "matched" << endl;
demás
cout << "not matched" << endl;

No coincide porque la expresión regular "man" no se pudo encontrar en toda la cadena de destino, "Aquí está mi creación."

Patrón

La expresión regular, "hombre" anterior, es muy simple. Las expresiones regulares no suelen ser tan simples. Las expresiones regulares tienen metacaracteres. Los metacaracteres son personajes con significados especiales. Un metacarácter es un personaje sobre personajes. Los metacaracteres de expresiones regulares de C ++ son:

^ $ \ . * + ? () [] |

Una expresión regular, con o sin metacaracteres, es un patrón.

Clases de personajes

Corchetes

Un patrón puede tener caracteres entre corchetes. Con esto, una posición particular en la cadena de destino coincidiría con cualquiera de los caracteres de los corchetes. Considere los siguientes objetivos:

"El gato está en la habitación."
"El murciélago está en la habitación."
"La rata está en la habitación."

La expresión regular, [cbr] en coincidiría con gato en el primer objetivo. Coincidiría con el murciélago en el segundo objetivo. Coincidiría con la rata en el tercer objetivo. Esto se debe a que "gato", "murciélago" o "rata" comienzan con "c", "b" o "r". El siguiente segmento de código ilustra esto:

regex reg ("[cbr] en");
if (regex_search ("El gato está en la habitación.", reg))
cout << "matched" << endl;
if (regex_search ("El murciélago está en la habitación.", reg))
cout << "matched" << endl;
if (regex_search ("La rata está en la habitación.", reg))
cout << "matched" << endl;

La salida es:

emparejado
emparejado
emparejado

Rango de caracteres

La clase, [cbr] en el patrón [cbr], coincidiría con varios caracteres posibles en el destino. Coincidiría con 'c' o 'b' o 'r' en el objetivo. Si el objetivo no tiene 'c', 'b' o 'r', seguido de "at", no habría ninguna coincidencia.

Algunas posibilidades como 'c' o 'b' o 'r' existen en un rango. El rango de dígitos, 0 a 9 tiene 10 posibilidades, y el patrón para eso es [0-9]. El rango de alfabetos en minúsculas, de la a a la z, tiene 26 posibilidades, y el patrón para eso es [a-z]. El rango de alfabetos en mayúsculas, de la A a la Z, tiene 26 posibilidades, y el patrón para eso es [A-Z]. - no es oficialmente un metacarácter, pero entre corchetes, indicaría un rango. Entonces, lo siguiente produce una coincidencia:

if (regex_search ("ID6id", regex ("[0-9]")))
cout << "matched" << endl;

Tenga en cuenta cómo se ha construido la expresión regular como segundo argumento. La coincidencia se produce entre el dígito, 6 en el rango, 0 a 9, y el 6 en el destino, "ID6id". El código anterior es equivalente a:

if (regex_search ("ID6id", regex ("[0123456789]")))
cout << "matched" << endl;

El siguiente código produce una coincidencia:

char str [] = "ID6iE";
if (regex_search (str, regex ("[a-z]")))
cout << "matched" << endl;

Tenga en cuenta que el primer argumento aquí es una variable de cadena y no el literal de cadena. La coincidencia es entre 'i' en [a-z] e 'i' en "ID6iE".

No olvides que un rango es una clase. Puede haber texto a la derecha del rango o a la izquierda del rango en el patrón. El siguiente código produce una coincidencia:

if (regex_search ("ID2id es un ID ", regex (" ID [0-9] id ")))
cout << "matched" << endl;

La coincidencia es entre "ID [0-9] id" e "ID2id". El resto de la cadena de destino, "es un ID", no coincide en esta situación.

Como se usa en el sujeto de expresión regular (regexes), la palabra clase en realidad significa un conjunto. Es decir, uno de los personajes del conjunto debe coincidir.

Nota: El guión - es un metacarácter solo entre corchetes, lo que indica un rango. No es un metacarácter en la expresión regular, fuera de los corchetes.

Negación

Se puede negar una clase que incluya un rango. Es decir, ninguno de los personajes del conjunto (clase) debe coincidir. Esto se indica con el metacarácter ^ al principio del patrón de clase, justo después del corchete de apertura. Entonces, [^ 0-9] significa hacer coincidir el carácter en la posición apropiada en el destino, que no es ningún carácter en el rango, 0 a 9 inclusive. Entonces, el siguiente código no producirá una coincidencia:

if (regex_search ("0123456789101112", regex ("[^ 0-9]")))
cout << "matched" << endl;
demás
cout << "not matched" << endl;

Se puede encontrar un dígito dentro del rango de 0 a 9 en cualquiera de las posiciones de la cadena de destino, "0123456789101112"; entonces no hay coincidencia - negación.

El siguiente código produce una coincidencia:

if (regex_search ("ABCDEFGHIJ", regex ("[^ 0-9]")))
cout << "matched" << endl;

No se pudo encontrar ningún dígito en el destino, "ABCDEFGHIJ"; entonces hay un partido.

[a-z] es un rango fuera de [^ a-z]. Y entonces [^ a-z] es la negación de [a-z].

[A-Z] es un rango fuera de [^ A-Z]. Y entonces [^ A-Z] es la negación de [A-Z].

Existen otras negaciones.

Coincidencia de espacios en blanco

"o \ t o \ r o \ n o \ f es un carácter de espacio en blanco. En el siguiente código, la expresión regular, "\ n" coincide con '\ n' en el destino:

if (regex_search ("De la línea uno.\ r \ nDe la línea dos.", expresión regular (" \ n ")))
cout << "matched" << endl;

Coincidencia de cualquier carácter de espacio en blanco

El patrón o la clase para coincidir con cualquier carácter de espacio en blanco es, [\ t \ r \ n \ f]. En el siguiente código, "coincide con:

if (regex_search ("uno dos", regex ("[\ t \ r \ n \ f]")))
cout << "matched" << endl;

Coincidir con cualquier carácter que no sea un espacio en blanco

El patrón o la clase para coincidir con cualquier carácter de espacio en blanco es, [^ \ t \ r \ n \ f]. El siguiente código produce una coincidencia porque no hay espacios en blanco en el destino:

if (regex_search ("1234abcd", regex ("[^ \ t \ r \ n \ f]")))
cout << "matched" << endl;

El período (.) en el patrón

El período (.) en el patrón coincide con cualquier carácter, incluido él mismo, excepto \ n, en el objetivo. Se produce una coincidencia en el siguiente código:

if (regex_search ("1234abcd", regex (".")))
cout << "matched" << endl;

No hay resultados coincidentes en el siguiente código porque el objetivo es "\ n".

if (regex_search ("\ n", regex (".")))
cout << "matched" << endl;
demás
cout << "not matched" << endl;

Nota: Dentro de una clase de caracteres con corchetes, el punto no tiene un significado especial.

Repeticiones coincidentes

Un carácter o un grupo de caracteres puede aparecer más de una vez dentro de la cadena de destino. Un patrón puede coincidir con esta repetición. Los metacaracteres, ?, *, + y se utilizan para hacer coincidir la repetición en el objetivo. Si x es un carácter de interés en la cadena de destino, los metacaracteres tienen los siguientes significados:

x *: significa coincidir con 'x' 0 o más veces, i.mi., cualquier cantidad de veces
x +: significa coincidir con 'x' 1 o más veces, i.mi., al menos una vez
X? : significa coincidir con 'x' 0 o 1 vez
x n,: significa coincidir con 'x' al menos no más veces. Nota la coma.
x n: coincide con 'x' exactamente n veces
x n, m: coincide con 'x' al menos n veces, pero no más de m veces.

Estos metacaracteres se llaman cuantificadores.

Ilustraciones

*

El * coincide con el carácter o grupo anterior, cero o más veces. "O *" coincide con "o" en "perro" de la cadena de destino. También coincide con "oo" en "libro" y "mirando". La expresión regular, "o *" coincide con "boooo" en "El animal booooed.". Nota: "o *" coincide con "dig", donde "o" aparece cero (o más) tiempo.

+

El + coincide con el carácter o grupo anterior, 1 o más veces. Compárelo con cero o más veces para *. Entonces, la expresión regular, "e +" coincide con "e" en "comer", donde "e" aparece una vez. "E +" también coincide con "ee" en "oveja", donde "e" aparece más de una vez. Nota: "e +" no coincidirá con "dig" porque en "dig", 'e' no aparece al menos una vez.

?

La ? coincide con el carácter o grupo anterior, 0 o 1 vez (y no más). Entonces, "e?"Coincide con" dig "porque" e "aparece en" dig ", tiempo cero. "mi?"Coincide con" set "porque" e "aparece en" set ", una vez. Nota: "e?”Todavía coincide con“ oveja ”; aunque hay dos 'e's en "oveja". Aquí hay un matiz - ver más adelante.

norte,

Esto coincide con al menos n repeticiones consecutivas de un carácter o grupo anterior. Entonces, la expresión regular, "e 2," coincide con las dos 'e's en el objetivo, "oveja", y las tres' e's en el objetivo "sheeep". "E 2," no coincide con "set", porque "set" solo tiene una 'e'.

norte

Esto coincide exactamente con n repeticiones consecutivas de un carácter o grupo anterior. Entonces, la expresión regular, "e 2" coincide con las dos 'e's en el objetivo, "oveja". "E 2" no coincide con "set" porque "set" solo tiene una 'e'. Bueno, "e 2" coincide con dos 'e's en el objetivo, "sheeep". Aquí hay un matiz - ver más adelante.

Nuevo Méjico

Esto coincide con varias repeticiones consecutivas de un carácter o grupo anterior, en cualquier lugar de n am, inclusive. Entonces, "e 1,3" no coincide con nada en "dig", que no tiene "e". Coincide con la una 'e' en "set", las dos 'e's en "sheep", las tres' e's en "sheeep" y las tres 'e's en "sheeeep". Hay un matiz en el último partido - ver más adelante.

Alternancia coincidente

Considere la siguiente cadena de destino en la computadora.

“La granja tiene cerdos de diferentes tamaños."

El programador puede querer saber si este objetivo tiene "cabra" o "conejo" o "cerdo". El código sería el siguiente:

char str [] = "La granja tiene cerdos de diferentes tamaños.";
if (regex_search (str, regex ("cabra | conejo | cerdo")))
cout << "matched" << endl;
demás
cout << "not matched" << endl;

El código produce una coincidencia. Tenga en cuenta el uso del carácter de alternancia, |. Puede haber dos, tres, cuatro y más opciones. C ++ primero intentará hacer coincidir la primera alternativa, "cabra", en cada posición de carácter en la cadena de destino. Si no tiene éxito con "cabra", prueba la siguiente alternativa, "conejo". Si no tiene éxito con "conejo", prueba la siguiente alternativa, "cerdo". Si "cerdo" falla, entonces C ++ pasa a la siguiente posición en el objetivo y comienza con la primera alternativa nuevamente.

En el código anterior, "cerdo" coincide.

Coincidencia de principio o final

Comenzando


Si ^ está al principio de la expresión regular, entonces el texto inicial de la cadena de destino puede coincidir con la expresión regular. En el siguiente código, el inicio del objetivo es "abc", que coincide:

if (regex_search ("abc y def", regex ("^ abc")))
cout << "matched" << endl;

No se produce ninguna coincidencia en el siguiente código:

if (regex_search ("Sí, abc y def", regex ("^ abc")))
cout << "matched" << endl;
demás
cout << "not matched" << endl;

Aquí, "abc" no está al principio del objetivo.

Nota: El carácter circunflejo, '^', es un metacarácter al comienzo de la expresión regular, que coincide con el comienzo de la cadena de destino. Sigue siendo un metacarácter al comienzo de la clase de personaje, donde niega la clase.

Final

Si $ está al final de la expresión regular, entonces el texto final de la cadena de destino puede coincidir con la expresión regular. En el siguiente código, el final del destino es "xyz", que coincide:

if (regex_search ("uvw y xyz", regex ("xyz $")))
cout << "matched" << endl;

No se produce ninguna coincidencia en el siguiente código:

if (regex_search ("uvw y xyz final", regex ("xyz $")))
cout << "matched" << endl;
demás
cout << "not matched" << endl;

Aquí, "xyz" no está al final del objetivo.

Agrupamiento

Los paréntesis se pueden usar para agrupar caracteres en un patrón. Considere la siguiente expresión regular:

"un concierto (pianista)"

El grupo aquí es "pianista" rodeado por los metacaracteres (y). En realidad, es un subgrupo, mientras que "un concierto (pianista)" es el grupo completo. Considera lo siguiente:

"El (pianista es bueno)"

Aquí, el subgrupo o subcadena es "el pianista es bueno".

Subcadenas con piezas comunes

Un contable es una persona que se ocupa de los libros. Imagina una biblioteca con un contador y una estantería. Suponga que una de las siguientes cadenas de destino está en la computadora:

"La biblioteca tiene una estantería que se admira.";
"Aquí está el contable.";
"El contable trabaja con la estantería.";

Suponga que el interés del programador no es saber cuál de estas oraciones está en la computadora. Aún así, su interés es saber si "estantería" o "contador" está presente en cualquier cadena de destino que esté en la computadora. En este caso, su expresión regular puede ser:

"estantería | contable."

Usando alternancia.

Observe que "libro", que es común a ambas palabras, se ha escrito dos veces, en las dos palabras del patrón. Para evitar escribir "libro" dos veces, la expresión regular estaría mejor escrita como:

"libro (estante | guardián)"

Aquí, el grupo, "estante | guardián" El metacarácter de alternancia todavía se ha utilizado, pero no para dos palabras largas. Se ha utilizado para las dos partes finales de las dos palabras largas. C ++ trata a un grupo como una entidad. Por lo tanto, C ++ buscará "estante" o "guardián" que viene inmediatamente después de "libro". La salida del siguiente código es "coincidente":

char str [] = "La biblioteca tiene una estantería que es admirada.";
if (regex_search (str, regex ("libro (estante | guardián)")))
cout << "matched" << endl;

Se han emparejado "estantería" y no "contador".

Las constantes regex_constants de icase y multiline

icase

La coincidencia distingue entre mayúsculas y minúsculas de forma predeterminada. Sin embargo, se puede hacer que no distinga entre mayúsculas y minúsculas. Para lograr esto, use la constante regex :: icase, como en el siguiente código:

if (regex_search ("Comentarios", regex ("alimentar", regex :: icase)))
cout << "matched" << endl;

La salida es "coincidente". Por lo tanto, "Comentarios" con "F" mayúscula se ha emparejado con "feed" con "f" minúscula. "Regex :: icase" se ha convertido en el segundo argumento del constructor regex (). Sin eso, la declaración no produciría una coincidencia.

Multilínea

Considere el siguiente código:

char str [] = "línea 1 \ nlínea 2 \ nlínea 3";
if (regex_search (str, regex ("^.PS
cout << "matched" << endl;
demás
cout << "not matched" << endl;

La salida "no coincide". La expresión regular, "^.* $, ”Coincide con la cadena de destino desde el principio hasta el final. ".* ”Significa cualquier carácter excepto \ n, cero o más veces. Entonces, debido a los caracteres de nueva línea (\ n) en el destino, no hubo coincidencias.

El objetivo es una cadena de varias líneas. Para poder '.'para que coincida con el carácter de nueva línea, se debe realizar la constante "regex :: multiline", el segundo argumento de la construcción regex (). El siguiente código ilustra esto:

char str [] = "línea 1 \ nlínea 2 \ nlínea 3";
if (regex_search (str, regex ("^.* $ ", expresión regular :: multilínea)))
cout << "matched" << endl;
demás
cout << "not matched" << endl;

Coincidencia de toda la cadena de destino

Para hacer coincidir toda la cadena de destino, que no tiene el carácter de nueva línea (\ n), se puede utilizar la función regex_match (). Esta función es diferente de regex_search (). El siguiente código ilustra esto:

char str [] = "primer segundo tercio";
if (regex_match (str, regex (".*segundo.* ")))
cout << "matched" << endl;

Hay un partido aqui. Sin embargo, tenga en cuenta que la expresión regular coincide con la cadena de destino completa, y la cadena de destino no tiene ningún '\ n'.

El objeto match_results

La función regex_search () puede tomar un argumento entre el objetivo y el objeto regex. Este argumento es el objeto match_results. La cadena completa emparejada (parte) y las subcadenas emparejadas se pueden conocer con ella. Este objeto es una matriz especial con métodos. El tipo de objeto match_results es cmatch (para cadenas literales).

Obtención de partidos

Considere el siguiente código:

char str [] = "La mujer que buscabas!";
cmatch m;
if (regex_search (str, m, regex ("w.metro.norte")))
cout << m[0] << endl;

La cadena de destino tiene la palabra "mujer". La salida es "mujer", que corresponde a la expresión regular, "w.metro.norte". En el índice cero, la matriz especial contiene la única coincidencia, que es "mujer".

Con las opciones de clase, solo la primera subcadena que se encuentra en el destino se envía a la matriz especial. El siguiente código ilustra esto:

cmatch m;
if (regex_search ("La rata, el gato, el murciélago!", m, regex (" [bcr] en ")))
cout << m[0] << endl;
cout << m[1] << endl;
cout << m[2] << endl;

La salida es "rata" desde el índice cero. m [1] y m [2] están vacíos.

Con alternativas, solo la primera subcadena que se encuentra en el destino se envía a la matriz especial. El siguiente código ilustra esto:

if (regex_search ("El conejo, la cabra, el cerdo!", m, regex (" cabra | conejo | cerdo ")))
cout << m[0] << endl;
cout << m[1] << endl;
cout << m[2] << endl;

La salida es "conejo" del índice cero. m [1] y m [2] están vacíos.

Agrupaciones

Cuando hay grupos involucrados, el patrón completo coincide, entra en la celda cero de la matriz especial. La siguiente subcadena encontrada va a la celda 1; la subcadena que sigue, entra en la celda 2; y así. El siguiente código ilustra esto:

if (regex_search ("El mejor librero de la actualidad!", m, regex (" libro ((sel) (ler)) ")))
cout << m[0] << endl;
cout << m[1] << endl;
cout << m[2] << endl;
cout << m[3] << endl;

La salida es:

librero
vendedor
sel
ler

Tenga en cuenta que el grupo (vendedor) viene antes que el grupo (sel).

Posición del partido

Se puede conocer la posición de coincidencia para cada subcadena en la matriz cmatch. El conteo comienza desde el primer carácter de la cadena de destino, en la posición cero. El siguiente código ilustra esto:

cmatch m;
if (regex_search ("El mejor librero de la actualidad!", m, regex (" libro ((sel) (ler)) ")))
cout << m[0] << "->" << m.position(0) << endl;
cout << m[1] << "->" << m.position(1) << endl;
cout << m[2] << "->" << m.position(2) << endl;
cout << m[3] << "->" << m.position(3) << endl;

Tenga en cuenta el uso de la propiedad de posición, con el índice de celda, como argumento. La salida es:

librero-> 5
vendedor-> 9
sel-> 9
ler-> 12

Buscar y reemplazar

Una nueva palabra o frase puede reemplazar la coincidencia. La función regex_replace () se utiliza para esto. Sin embargo, esta vez, la cadena donde ocurre el reemplazo es el objeto de cadena, no el literal de cadena. Entonces, la biblioteca de cadenas debe incluirse en el programa. Ilustración:

#incluir
#incluir
#incluir
usando el espacio de nombres std;
int main ()

string str = "Aquí viene mi hombre. Ahí va tu hombre.";
string newStr = regex_replace (str, regex ("hombre"), "mujer");
cout << newStr << endl;
return 0;

La función regex_replace (), como se codifica aquí, reemplaza todas las coincidencias. El primer argumento de la función es el objetivo, el segundo es el objeto regex y el tercero es la cadena de reemplazo. La función devuelve una nueva cadena, que es el objetivo pero que tiene el reemplazo. La salida es:

"Aquí viene mi mujer. Ahí va tu mujer."

Conclusión

La expresión regular usa patrones para hacer coincidir subcadenas en la cadena de secuencia de destino. Los patrones tienen metacaracteres. Las funciones más utilizadas para las expresiones regulares de C ++ son: regex_search (), regex_match () y regex_replace (). Una expresión regular es un patrón entre comillas dobles. Sin embargo, estas funciones toman el objeto regex como argumento y no solo la expresión regular. La expresión regular debe convertirse en un objeto de expresión regular antes de que estas funciones puedan usarlo.

Cómo instalar League Of Legends en Ubuntu 14.04
Si eres fanático de League of Legends, esta es una oportunidad para que pruebes League of Legends. Tenga en cuenta que LOL es compatible con PlayOnLin...
Instale el último juego de estrategia de OpenRA en Ubuntu Linux
OpenRA es un motor de juego de estrategia en tiempo real libre / gratuito que recrea los primeros juegos de Westwood como el clásico Command & Conquer...
Instale el último emulador de Dolphin para Gamecube y Wii en Linux
Dolphin Emulator te permite jugar los juegos de Gamecube y Wii que elijas en computadoras personales con Linux (PC). Al ser un emulador de juegos de ...