Bases d'expression régulière en C ++

Bases d'expression régulière en C ++
Considérez la phrase suivante dans les citations: "Voici mon homme."

Cette chaîne peut être à l'intérieur de l'ordinateur, et l'utilisateur peut vouloir savoir s'il a le mot «homme». S'il a le mot homme, il peut alors vouloir changer le mot «homme» en «femme»; afin que la chaîne soit lue:

"Voici ma femme."

Il existe de nombreux autres désirs comme ceux-ci de l'utilisateur de l'ordinateur; Certains sont complexes. L'expression régulière, abrégée, regex, fait l'objet de la gestion de ces problèmes par l'ordinateur. C ++ est livré avec une bibliothèque appelée regex. Ainsi, un programme C ++ pour gérer Regex devrait commencer:

#inclure
#inclure
Utilisation de Namespace Std;

Cet article explique les bases de l'expression régulière en C++.

Contenu de l'article

  • Fondamentaux d'expression régulière
  • Modèle
  • Classes de personnages
  • Espaces blancs assortis
  • La période (.) dans le motif
  • Répétitions correspondantes
  • Alternance correspondante
  • Début ou fin correspondant
  • Regroupement
  • L'ICase et la multibline regex_constants
  • Correspondant à l'ensemble de la cible
  • L'objet Match_Results
  • Position de match
  • Rechercher et remplacer
  • Conclusion

Fondamentaux d'expression régulière

Expirat

Une chaîne comme «voici mon homme."Ci-dessus est la séquence cible ou la chaîne cible ou simplement, cible. «L'homme», qui a été recherché, est l'expression régulière, ou tout simplement, regex.

Correspondant à

L'appariement se produit lorsque le mot ou la phrase qui est recherchée est situé. Après correspondance, un remplacement peut avoir lieu. Par exemple, après que «l'homme» est situé au-dessus, il peut être remplacé par «femme».

Correspondance simple

Le programme suivant montre comment le mot «homme» est égalé.

#inclure
#inclure
Utilisation de Namespace Std;
int main()

Regex reg ("man");
if (regex_search ("voici mon homme.", reg))
couter << "matched" << endl;
autre
couter << "not matched" << endl;
retour 0;

La fonction regex_search () renvoie true s'il y a une correspondance et renvoie false si aucune correspondance ne se produit. Ici, la fonction prend deux arguments: le premier est la chaîne cible, et le second est l'objet regex. Le regex lui-même est "l'homme", en double quot. La première instruction de la fonction Main () forme l'objet regex. Regex est un type, et Reg est l'objet regex. La sortie du programme ci-dessus est "correspondante", car "l'homme" est vu dans la chaîne cible. Si "l'homme" n'était pas vu dans la cible, regex_search () serait revenu faux et la sortie aurait été "non appariée".

La sortie du code suivant n'est «pas appariée»:

Regex reg ("man");
if (regex_search ("voici ma fabrication.", reg))
couter << "matched" << endl;
autre
couter << "not matched" << endl;

Pas égalé parce que "l'homme" regex n'a pas pu être trouvé dans toute la chaîne cible, "voici ma fabrication."

Modèle

L'expression régulière, «l'homme» ci-dessus, est très simple. Les regex ne sont généralement pas aussi simples. Des expressions régulières ont des métacharacteurs. Les métacharacteurs sont des personnages ayant des significations spéciales. Un métacharacter est un personnage sur les personnages. C ++ Regex Metacharacters sont:

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

Un regex, avec ou sans métacharacteurs, est un modèle.

Classes de personnages

Crochets

Un motif peut avoir des caractères entre crochets. Avec cela, une position particulière dans la chaîne cible correspondrait à tous les caractères des crochets. Considérez les cibles suivantes:

"Le chat est dans la pièce."
"La batte est dans la pièce."
"Le rat est dans la pièce."

Le regex, [CBR], correspondait à Cat dans la première cible. Cela correspondrait à Bat dans la deuxième cible. Il correspondrait à Rat dans la troisième cible. C'est parce que, «chat» ou «bat» ou «rat» commence par «c» ou «b» ou «r». Le segment de code suivant l'illustre:

regex reg ("[cbr] at");
if (regex_search ("le chat est dans la pièce.", reg))
couter << "matched" << endl;
if (regex_search ("la batte est dans la pièce.", reg))
couter << "matched" << endl;
if (regex_search ("le rat est dans la pièce.", reg))
couter << "matched" << endl;

La sortie est:

assorti
assorti
assorti

Gamme de caractères

La classe, [CBR] dans le motif [CBR], correspondrait à plusieurs caractères possibles dans la cible. Il correspondrait à «c» ou «b» ou «r» dans la cible. Si la cible n'a aucun «C» ou «B» ou «R», suivi de «AT», il n'y aurait pas de match.

Certaines possibilités comme «C» ou «B» ou «R» existent dans une gamme. La gamme de chiffres, 0 à 9 a 10 possibilités, et le modèle est [0-9]. La gamme des alphabets minuscules, A à Z, a 26 possibilités, et le modèle est [A-Z]. La gamme d'alphabets majuscules, A à Z, a 26 possibilités, et le modèle est [A-Z]. - n'est pas officiellement un Metacharacter, mais entre les crochets, cela indiquerait une gamme. Ainsi, ce qui suit produit un match:

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

Notez comment le regex a été construit comme le deuxième argument. Le match se produit entre le chiffre, 6 dans la plage, 0 à 9, et le 6 dans la cible, «id6id». Le code ci-dessus est équivalent à:

if (regex_search ("id6id", regex ("[0123456789]")))
couter << "matched" << endl;

Le code suivant produit une correspondance:

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

Notez que le premier argument ici est une variable de chaîne et non la chaîne littérale. Le match est entre «i» dans [a-z] et «i» dans «id6ie».

N'oubliez pas qu'une gamme est une classe. Il peut y avoir du texte à droite de la gamme ou à gauche de la plage dans le motif. Le code suivant produit une correspondance:

if (regex_search ("id2idpost-95222 -__ ddelink__294_3116034780"> est un id ", regex (" id [0-9] id ")))
couter << "matched" << endl;

Le match est entre «ID [0-9] ID» et «ID2ID». Le reste de la chaîne cible, «est un identifiant», n'est pas égalé dans cette situation.

Comme utilisé dans le sujet d'expression régulière (regex), la classe de mots signifie en fait un ensemble. C'est-à-dire que l'un des personnages de l'ensemble est de correspondre.

Remarque: le trait d'union - est un métacharacter uniquement entre crochets, indiquant une gamme. Ce n'est pas un métacharacter dans le regex, à l'extérieur des crochets.

Négation

Une classe comprenant une gamme peut être annulée. C'est-à-dire que non des personnages de l'ensemble (classe) ne devraient correspondre. Ceci est indiqué par le ^ Metacharacter au début du modèle de classe, juste après le support carré d'ouverture. Ainsi, [^ 0-9] signifie correspondre au caractère à la position appropriée dans la cible, qui n'est pas un caractère dans la plage, 0 à 9 inclus. Ainsi, le code suivant ne produira pas de correspondance:

if (regex_search ("0123456789101112", regex ("[^ 0-9]")))
couter << "matched" << endl;
autre
couter << "not matched" << endl;

Un chiffre dans la plage de 0 à 9 a pu être trouvé dans l'une des positions de chaîne cible, «0123456789101112»; Il n'y a donc pas de correspondance - négation.

Le code suivant produit une correspondance:

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

Aucun chiffre n'a pu être trouvé dans la cible, «abcdefghij»; donc il y a un match.

[A-Z] est une plage à l'extérieur [^ a-z]. Et donc [^ a-z] est la négation de [a-z].

[A-Z] est une plage à l'extérieur [^ a-z]. Et donc [^ a-z] est la négation de [a-z].

D'autres négations existent.

Espaces blancs assortis

"ou \ t ou \ r ou \ n ou \ f est un caractère blanc. Dans le code suivant, le regex, «\ n» correspond à '\ n' dans la cible:

if (regex_search ("de la ligne un.\ r \ nof ligne deux.", regex (" \ n ")))
couter << "matched" << endl;

Correspondant à tout personnage blanc

Le motif ou la classe pour correspondre à tout caractère d'espace blanc est [\ t \ r \ n \ f]. Dans le code suivant, "est apparié:

if (regex_search ("un deux", regex ("[\ t \ r \ n \ f]")))
couter << "matched" << endl;

Correspondant à tout personnage non blanc

Le motif ou la classe pour correspondre à tout caractère d'espace non blanc est, [^ \ t \ r \ n \ f]. Le code suivant produit une correspondance car il n'y a pas d'espace blanc dans la cible:

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

La période (.) dans le motif

La période (.) dans le motif correspond à tout caractère incluant lui-même, sauf \ n, dans la cible. Une correspondance est produite dans le code suivant:

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

Aucun résultat correspondant dans le code suivant car la cible est «\ n».

if (regex_search ("\ n", regex (".")))
couter << "matched" << endl;
autre
couter << "not matched" << endl;

Remarque: à l'intérieur d'une classe de caractères avec des crochets, la période n'a pas de signification particulière.

Répétitions correspondantes

Un caractère ou un groupe de caractères peut se produire plus d'une fois dans la chaîne cible. Un modèle peut correspondre à cette répétition. Les métacharacteurs, ?, *, + et sont utilisés pour faire correspondre la répétition dans la cible. Si x est un caractère d'intérêt dans la chaîne cible, les métacharacteurs ont les significations suivantes:

x *: signifie faire correspondre 'x' 0 ou plus, je.e., un certain nombre de fois
x +: signifie faire correspondre «x» 1 fois ou plus, je.e., au moins une fois
X? : signifie correspondre à 'x' 0 ou 1 fois
x n,: signifie faire correspondre 'x' au moins n ou plus de fois. Notez la virgule.
x n: correspondre à «x» exactement n fois
x n, m: correspondre 'x' au moins n fois, mais pas plus que m fois.

Ces métacharacteurs sont appelés quantificateurs.

Illustrations

*

Le * correspond au caractère précédent ou au groupe précédent, zéro ou plus de fois. "O *" correspond à "O 'dans" Dog "de la chaîne cible. Il correspond également à "OO" dans "Book" et "Looking". Le regex, "O *" correspond à "Booo" dans "The Animal Booooed.". Remarque: «O *» correspond à «Dig», où «O» se produit zéro (ou plus) le temps.

+

Le + correspond au caractère précédent ou au groupe précédent, 1 fois ou plus. Le contraster avec zéro ou plus de fois pour *. Ainsi, le regex, «e +» correspond à «E» dans «manger», où «e» se produit une fois. «E +» correspond également à «ee» dans «mouton», où «e» se produit plus d'une fois. Remarque: «E +» ne correspondra pas à «creuser» car dans «Dig», «E» ne se produit pas au moins une fois.

?

Le ? correspond au caractère précédent ou au groupe précédent, 0 ou 1 fois (et pas plus). Alors, «E?"Correspond à" Dig "parce que" e "se produit dans" Dig ", zéro temps. "E?«Correspond à« set »parce que« e »se produit dans« set », une fois. Remarque: «E?«Correspond toujours aux« moutons »; Bien qu'il y ait deux «e moutons». Il y a une nuance ici - voir plus tard.

n,

Cela correspond au moins à N répétitions consécutives d'un personnage précédent ou d'un groupe précédent. Ainsi, le regex, «e 2,» correspond aux deux 'e dans la cible, «moutons», et les trois' E dans la cible «Sheeep». "E 2," ne correspond pas à "set", car "set" n'a qu'un seul "e".

n

Cela correspond exactement à N répétitions consécutives d'un personnage précédent ou d'un groupe précédent. Ainsi, le regex, "e 2" correspond aux deux "e dans la cible," mouton ". "E 2" ne correspond pas à "set" parce que "set" n'a qu'un seul "e". Eh bien, "E 2" correspond à deux 'e dans la cible, "Sheeep". Il y a une nuance ici - voir plus tard.

n, m

Cela correspond à plusieurs répétitions consécutives d'un personnage précédent ou d'un groupe précédent, de N à M, inclusif. Ainsi, "E 1,3" ne correspond à rien dans "Dig", qui n'a pas "e '. Il correspond à celui «e» dans «set», les deux «e dans« mouton », les trois« e dans «Sheeep» et les trois «e dans« Sheeeep ». Il y a une nuance lors du dernier match - voir plus tard.

Alternance correspondante

Considérez la chaîne cible suivante dans l'ordinateur.

«La ferme a des porcs de différentes tailles."

Le programmeur peut vouloir savoir si cette cible a «chèvre» ou «lapin» ou «cochon». Le code serait le suivant:

char Str [] = "La ferme a des porcs de différentes tailles."
if (regex_search (str, regex ("chèvre | lapin | pig")))
couter << "matched" << endl;
autre
couter << "not matched" << endl;

Le code produit une correspondance. Remarquez l'utilisation du caractère d'alternance, |. Il peut y avoir deux, trois, quatre et plus d'options. C ++ essaiera d'abord de faire correspondre la première alternative, «chèvre», à chaque position de caractère dans la chaîne cible. S'il ne réussit pas avec «chèvre», il essaie la prochaine alternative, «lapin». S'il ne réussit pas avec «lapin», il essaie la prochaine alternative, «cochon». Si «Pig» échoue, alors C ++ passe à la position suivante dans la cible et recommence avec la première alternative.

Dans le code ci-dessus, «Pig» est apparié.

Début ou fin correspondant

Début


Si ^ est au début du Regex, alors le texte de début de la chaîne cible peut être égalé par le regex. Dans le code suivant, le début de la cible est «ABC», qui est apparié:

if (regex_search ("abc et def", regex ("^ abc")))
couter << "matched" << endl;

Aucune correspondance n'a lieu dans le code suivant:

if (regex_search ("Oui, ABC et Def", regex ("^ ABC")))
couter << "matched" << endl;
autre
couter << "not matched" << endl;

Ici, «ABC» n'est pas au début de la cible.

Remarque: le caractère circonflexe, '^', est un métacharacter au début du regex, correspondant au début de la chaîne cible. C'est toujours un métacharacter au début de la classe de personnage, où il annule la classe.

Fin

Si $ est à la fin du regex, alors le texte de fin de la chaîne cible peut être égalé par le regex. Dans le code suivant, la fin de la cible est «XYZ», qui est appariée:

if (regex_search ("uvw et xyz", regex ("xyz $")))
couter << "matched" << endl;

Aucune correspondance n'a lieu dans le code suivant:

if (regex_search ("uvw et xyz final", regex ("xyz $")))
couter << "matched" << endl;
autre
couter << "not matched" << endl;

Ici, «xyz» n'est pas à la fin de la cible.

Regroupement

Les parenthèses peuvent être utilisées pour regrouper les caractères d'un modèle. Considérez le regex suivant:

"Un concert (pianiste)"

Le groupe ici est «pianiste» entouré des métacharacteurs (et). C'est en fait un sous-groupe, tandis que «un concert (pianiste)» est tout le groupe. Considérer ce qui suit:

"Le (pianiste est bon)"

Ici, le sous-groupe ou la sous-chaîne est: «Le pianiste est bon».

Sous-cordes avec des pièces communes

Un comptable est une personne qui s'occupe des livres. Imaginez une bibliothèque avec un comptable et une bibliothèque. Supposons que l'une des chaînes cibles suivantes se trouvent dans l'ordinateur:

"La bibliothèque a une bibliothèque admirée."
"Voici le comptable."
"Le comptable travaille avec la bibliothèque."

Supposons que l'intérêt du programmeur n'est pas de savoir lequel de ces phrases se trouve dans l'ordinateur. Pourtant, son intérêt est de savoir si «bibliothèque» ou «comptable» est présent dans la chaîne cible dans l'ordinateur. Dans ce cas, son expulse peut être:

"Bibs à bibliothèque | comptable."

Utilisation de l'alternance.

Remarquez que le «livre», qui est commun aux deux mots, a été dactylographié deux fois, dans les deux mots du modèle. Pour éviter de taper «réserver» deux fois, le regex serait mieux écrit comme:

"Livre (étagère | gardien)"

Ici, le groupe, «Shelf | Keeper», l'alternance Metacharacter a toujours été utilisée, mais pas pour deux longs mots. Il a été utilisé pour les deux parties finales des deux longs mots. C ++ traite un groupe comme une entité. Ainsi, C ++ recherchera «étagère» ou «gardien» qui vient immédiatement après le «livre». La sortie du code suivant est «correspondante»:

Char Str [] = "La bibliothèque a une bibliothèque admirée."
if (regex_search (str, regex ("livre (étagère | gardien)")))
couter << "matched" << endl;

«Libshelf» et non «Bookkeeper» ont été égalés.

L'ICase et la multibline regex_constants

icase

La correspondance est sensible à la casse par défaut. Cependant, il peut être rendu insensible au cas. Pour y parvenir, utilisez la constante regex :: iCase, comme dans le code suivant:

if (regex_search ("feedback", regex ("feed", regex :: iCase))))
couter << "matched" << endl;

La sortie est «correspondante». Donc, «commentaires» avec la majuscule «f» a été apparié par «se nourrir» avec les minuscules «f». "Regex :: ICase" a été fait le deuxième argument du constructeur regex (). Sans cela, la déclaration ne produirait pas de match.

Multiligne

Considérez le code suivant:

char str [] = "ligne 1 \ nline 2 \ nline 3";
if (regex_search (str, regex ("^.* $ ")))
couter << "matched" << endl;
autre
couter << "not matched" << endl;

La sortie est «non appariée». Le regex, «^.* $ », Correspond à la chaîne cible de son début à sa fin. ".* ”Signifie tout caractère sauf \ n, zéro ou plus de fois. Donc, en raison des caractères Newline (\ n) dans la cible, il n'y avait pas de correspondance.

La cible est une chaîne multiline. Afin de.«Pour correspondre au personnage de Newline, le« regex :: multiline »constant doit être fait, le deuxième argument de la construction regex (). Le code suivant illustre ceci:

char str [] = "ligne 1 \ nline 2 \ nline 3";
if (regex_search (str, regex ("^.* $ ", regex :: multiline))))
couter << "matched" << endl;
autre
couter << "not matched" << endl;

Correspondant à l'ensemble de la chaîne cible

Pour correspondre à l'ensemble de la chaîne cible, qui n'a pas le caractère Newline (\ n), la fonction regex_match () peut être utilisée. Cette fonction est différente de regex_search (). Le code suivant illustre ceci:

char str [] = "premier deuxième tiers";
if (regex_match (str, regex (".*deuxième.* ")))
couter << "matched" << endl;

Il y a un match ici. Cependant, notez que le regex correspond à l'ensemble de la chaîne cible et que la chaîne cible n'a pas de '\ n'.

L'objet Match_Results

La fonction regex_search () peut prendre un argument entre la cible et l'objet regex. Cet argument est l'objet Match_Results. La chaîne entière (partie) correspondante et les sous-traces correspondaient. Cet objet est un tableau spécial avec des méthodes. Le type d'objet Match_Results est cmatch (pour les littéraux de chaîne).

Obtenir des matchs

Considérez le code suivant:

Char Str [] = "La femme que vous recherchiez!"
cmatch m;
if (regex_search (str, m, regex ("w.m.n ")))
couter << m[0] << endl;

La chaîne cible a le mot «femme». La sortie est «femme», ce qui correspond au regex, «w.m.n ”. À Index Zero, le tableau spécial détient le seul match, qui est «femme».

Avec les options de classe, seule la première sous-chaîne trouvée dans la cible est envoyée au tableau spécial. Le code suivant illustre ceci:

cmatch m;
if (regex_search ("le rat, le chat, la batte!", m, regex (" [bcr] à ")))
couter << m[0] << endl;
couter << m[1] << endl;
couter << m[2] << endl;

La sortie est «rat» de l'index zéro. m [1] et m [2] sont vides.

Avec des alternatives, seule la première sous-chaîne trouvée dans la cible, est envoyée au tableau spécial. Le code suivant illustre ceci:

if (regex_search ("le lapin, la chèvre, le cochon!", m, regex (" chèvre | lapin | cochon ")))
couter << m[0] << endl;
couter << m[1] << endl;
couter << m[2] << endl;

La sortie est «lapin» de l'index zéro. m [1] et m [2] sont vides.

Groupes

Lorsque les groupes sont impliqués, le modèle complet correspondait, entre dans la cellule zéro du tableau spécial. La sous-chaîne suivante trouvée entre dans la cellule 1; La sous-chaîne qui suit, entre dans la cellule 2; et ainsi de suite. Le code suivant illustre ceci:

if (regex_search ("meilleur libraire aujourd'hui!", M, regex (" livre ((sel) (ler)) ")))
couter << m[0] << endl;
couter << m[1] << endl;
couter << m[2] << endl;
couter << m[3] << endl;

La sortie est:

libraire
vendeur
Sel
ler

Notez que le groupe (vendeur) vient avant le groupe (SEL).

Position de match

La position de correspondance pour chaque sous-chaîne dans le tableau cmatch peut être connue. Le comptage commence à partir du premier caractère de la chaîne cible, à la position zéro. Le code suivant illustre ceci:

cmatch m;
if (regex_search ("meilleur libraire aujourd'hui!", M, regex (" livre ((sel) (ler)) ")))
couter << m[0] << "->" << m.position(0) << endl;
couter << m[1] << "->" << m.position(1) << endl;
couter << m[2] << "->" << m.position(2) << endl;
couter << m[3] << "->" << m.position(3) << endl;

Notez l'utilisation de la propriété de position, avec l'indice de cellule, comme argument. La sortie est:

libraire-> 5
Vendeur-> 9
Sel-> 9
ler-> 12

Rechercher et remplacer

Un nouveau mot ou phrase peut remplacer le match. La fonction regex_replace () est utilisée pour cela. Cependant, cette fois, la chaîne où se produit le remplacement est l'objet de chaîne, pas la chaîne littérale. Ainsi, la bibliothèque de chaînes doit être incluse dans le programme. Illustration:

#inclure
#inclure
#inclure
Utilisation de Namespace Std;
int main()

String str = "ici, vient mon homme. Voilà votre homme."
String newstr = regex_replace (str, regex ("man"), "femme");
couter << newStr << endl;
retour 0;

La fonction regex_replace (), telle que codée ici, remplace toutes les correspondances. Le premier argument de la fonction est la cible, la seconde est l'objet Regex, et le troisième est la chaîne de remplacement. La fonction renvoie une nouvelle chaîne, qui est la cible mais ayant le remplacement. La sortie est:

«Voici ma femme. Voilà ta femme."

Conclusion

L'expression régulière utilise des modèles pour faire correspondre les sous-chaînes dans la chaîne de séquence cible. Les modèles ont des métacharacteurs. Les fonctions couramment utilisées pour les expressions régulières C ++ sont: regex_search (), regex_match () et regex_replace (). Un regex est un motif en double quot. Cependant, ces fonctions prennent l'objet regex comme argument et pas seulement le regex. Le regex doit être transformé en un objet regex avant que ces fonctions puissent l'utiliser.