Notions de base sur les expressions régulières en C++

Regular Expression Basics C



Considérez la phrase suivante entre guillemets :

'Voici mon homme.'

Cette chaîne peut être à l'intérieur de l'ordinateur et l'utilisateur peut vouloir savoir si elle contient le mot man. S'il contient le mot homme, il peut alors vouloir changer le mot homme en femme ; de sorte que la chaîne doit lire :







'Voici ma femme.'

Il y a beaucoup d'autres désirs comme ceux-ci de la part de l'utilisateur d'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 les expressions régulières devrait commencer par :



#comprendre

#comprendre

en utilisant l'espace de noms std;

Cet article explique les bases des expressions régulières en C++.



Contenu de l'article

Principes fondamentaux des expressions régulières

Regex

Une chaîne comme Voici mon homme. ci-dessus est la séquence cible ou la chaîne cible ou simplement, la cible. man, qui a été recherché, est l'expression régulière, ou simplement, regex.





Correspondant à

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

Correspondance simple

Le programme suivant montre comment le mot man est mis en correspondance.



#comprendre

#comprendre

en utilisant l'espace de noms std;

entierprincipale()
{

regex('homme');
si (recherche_regex('Voici mon homme.',reg))
cout<< 'correspondant' <<fin;
autre
cout<< 'pas adapté' <<fin;

revenir 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. La regex elle-même est 'man', entre guillemets. 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 « correspondée », car « man » est vu dans la chaîne cible. Si 'man' n'avait pas été vu dans la cible, regex_search() aurait renvoyé false et la sortie aurait été 'pas de correspondance'.

La sortie du code suivant ne correspond pas :

regex('homme');
si (recherche_regex(« Voici ma fabrication. »,reg))
cout<< 'correspondant' <<fin;
autre
cout<< 'pas adapté' <<fin;

Ne correspond pas car l'expression régulière 'man' n'a pas pu être trouvée dans l'intégralité de la chaîne cible, 'Voici ma fabrication'.

Modèle

L'expression régulière, man ci-dessus, est très simple. Les expressions régulières ne sont généralement pas si simples. Les expressions régulières ont des métacaractères. Les métacaractères sont des caractères ayant une signification particulière. Un métacaractère est un caractère sur les personnages. Les métacaractères regex C++ sont :

^$ .* + ? ( ) [ ] { } |

Une expression régulière, avec ou sans métacaractères, est un modèle.

Classes de personnages

Crochets

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

« Le chat est dans la pièce.

« La chauve-souris est dans la pièce.

« Le rat est dans la pièce.

L'expression régulière, [cbr]at correspondrait à cat dans la première cible. Il correspondrait à la batte dans la deuxième cible. Il correspondrait au rat dans la troisième cible. C'est parce que, chat ou chauve-souris ou rat commence par 'c' ou 'b' ou 'r'. Le segment de code suivant illustre cela :

regex('[cbr]à');
si (recherche_regex(« Le chat est dans la pièce.,reg))
cout<< 'correspondant' <<fin;
si (recherche_regex(« La chauve-souris est dans la pièce.,reg))
cout<< 'correspondant' <<fin;
si (recherche_regex(« Le rat est dans la pièce.,reg))
cout<< 'correspondant' <<fin;

La sortie est :

apparié

apparié

apparié

Gamme de caractères

La classe, [cbr] dans le modèle [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 des 'c' ou 'b' ou 'r', suivi de at, il n'y aurait pas de correspondance.

Certaines possibilités comme « c » ou « b » ou « r » existent dans une plage. La plage de chiffres, 0 à 9 a 10 possibilités, et le modèle pour cela est [0-9]. La gamme d'alphabets minuscules, a à z, a 26 possibilités, et le modèle pour cela est [a-z]. La gamme d'alphabets majuscules, A à Z, a 26 possibilités, et le modèle pour cela est [A-Z]. – n'est pas officiellement un métacaractère, mais entre crochets, il indiquerait une plage. Ainsi, ce qui suit produit une correspondance :

si (recherche_regex('ID6id',expression régulière('[0-9]')))

cout<< 'correspondant' <<fin;

Notez comment l'expression régulière a été construite en tant que deuxième argument. La correspondance se produit entre le chiffre, 6 dans la plage, 0 à 9, et le 6 dans la cible, ID6id. Le code ci-dessus est équivalent à :

si (recherche_regex('ID6id',expression régulière('[0123456789]')))

cout<< 'correspondant' <<fin;

Le code suivant produit une correspondance :

carboniserp[] = 'ID6iE';

si (recherche_regex(p,expression régulière('[a-z]')))

cout<< 'correspondant' <<fin;

Notez que le premier argument ici est une variable de chaîne et non le littéral de chaîne. La correspondance 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 plage ou à gauche de la plage dans le modèle. Le code suivant produit une correspondance :

si (recherche_regex('ID2id est une pièce d'identité',expression régulière('ID[0-9]id')))

cout<< 'correspondant' <<fin;

La correspondance est entre ID[0-9]id et ID2id. Le reste de la chaîne cible, est un ID, n'est pas mis en correspondance dans cette situation.

Tel qu'il est utilisé dans le sujet des expressions régulières (regex), le mot classe signifie en fait un ensemble. C'est-à-dire que l'un des personnages de l'ensemble doit correspondre.

Remarque : Le tiret – est un métacaractère uniquement entre crochets, indiquant une plage. Ce n'est pas un métacaractère dans l'expression régulière, en dehors des crochets.

Négation

Une classe comprenant une plage peut être annulée. C'est-à-dire qu'aucun des caractères de l'ensemble (classe) ne doit correspondre. Ceci est indiqué par le métacaractère ^ au début du modèle de classe, juste après le crochet ouvrant. Ainsi, [^0-9] signifie faire correspondre le caractère à la position appropriée dans la cible, qui n'est pas un caractère dans la plage 0 à 9 inclus. Le code suivant ne produira donc pas de correspondance :

si (recherche_regex('0123456789101112',expression régulière('[^ 0-9]')))

cout<< 'correspondant' <<fin;

autre

cout<< 'pas adapté' <<fin;

Un chiffre compris entre 0 et 9 peut être trouvé dans n'importe quelle position de chaîne cible, 0123456789101112 ; donc il n'y a pas de correspondance – la négation.

Le code suivant produit une correspondance :

si (recherche_regex('ABCDEFGHIJ',expression régulière('[^ 0-9]')))

cout<< 'correspondant' <<fin;

Aucun chiffre n'a pu être trouvé dans la cible, ABCDEFGHIJ, ; donc il y a correspondance.

[a-z] est une plage en dehors de [^a-z]. Et donc [^a-z] est la négation de [a-z].

[A-Z] est une plage en dehors de [^A-Z]. Et donc [^A-Z] est la négation de [A-Z].

D'autres négations existent.

Correspondance des espaces blancs

' ' ou ou ou ou f est un caractère d'espacement. Dans le code suivant, l'expression régulière, correspond à ' ' dans la cible :

si (recherche_regex(« De la première ligne. De la ligne deux.,expression régulière(' ')))

cout<< 'correspondant' <<fin;

Correspondance avec n'importe quel caractère d'espacement

Le modèle ou la classe pour correspondre à n'importe quel caractère d'espace blanc est, [ f]. Dans le code suivant, ' ' est mis en correspondance :

si (recherche_regex('un deux',expression régulière('[ F] ')))

cout<< 'correspondant' <<fin;

Correspondance avec n'importe quel caractère non blanc

Le modèle ou la classe correspondant à tout caractère autre qu'un espace blanc est [^ f]. Le code suivant produit une correspondance car il n'y a pas d'espace dans la cible :

si (recherche_regex('1234abcd',expression régulière('[^ F] ')))

cout<< 'correspondant' <<fin;

Le point (.) dans le motif

Le point (.) dans le modèle correspond à n'importe quel caractère, y compris lui-même, à l'exception de , dans la cible. Une correspondance est produite dans le code suivant :

si (recherche_regex('1234abcd',expression régulière('.')))

cout<< 'correspondant' <<fin;

Aucun résultat correspondant dans le code suivant car la cible est .

si (recherche_regex(' ',expression régulière('.')))

cout<< 'correspondant' <<fin;

autre

cout<< 'pas adapté' <<fin;

Remarque : à l'intérieur d'une classe de caractères entre crochets, le point n'a pas de signification particulière.

Répétitions correspondantes

Un caractère ou un groupe de caractères peut apparaître plusieurs fois dans la chaîne cible. Un motif peut correspondre à cette répétition. Les métacaractères ?, *, + 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étacaractères ont les significations suivantes :

X* :signifie correspondre'X' 0ou plusieurs fois,je.Et.,un nombre quelconque de fois

X+ :signifie correspondre'X' 1ou plusieurs fois,je.Et.,au moins une fois

X? :signifie correspondre'X' 0ou1 temps

X{m,}:signifie correspondre'X'au moins n fois ou plus.Noterla virgule.

X{m} :rencontre'X'exactement n fois

X{m,m}:rencontre'X'au moins n fois,mais pas plus de m fois.

Ces métacaractères sont appelés quantificateurs.

Illustrations

*

Le * correspond au caractère ou au groupe précédent, zéro ou plusieurs fois. o* correspond à « o » dans le chien de la chaîne cible. Il correspond également à oo dans le livre et à la recherche. L'expression régulière, o* correspond à boooo dans L'animal booooed.. Remarque : o* correspond à dig, où 'o' apparaît à zéro (ou plus).

+

Le + correspond au caractère précédent ou au groupe précédent, 1 ou plusieurs fois. Comparez-le avec zéro ou plusieurs fois pour *. Ainsi, l'expression régulière e+ correspond à « e » dans manger, où « e » apparaît une fois. e+ correspond également à ee chez le mouton, où « e » apparaît plus d'une fois. Remarque : e+ ne correspondra pas à dig car dans dig, « e » ne se produit pas au moins une fois.

?

Les ? 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' apparaît dans dig, zéro temps. e? correspond à l'ensemble parce que 'e' apparaît dans l'ensemble, une fois. Remarque : e ? correspond toujours aux moutons; bien qu'il y ait deux 'e' dans le mouton. Il y a une nuance ici – voir plus loin.

{n,}

Cela correspond à au moins n répétitions consécutives d'un caractère précédent ou d'un groupe précédent. Ainsi, la regex, e{2,} correspond aux deux 'e' dans la cible, mouton, et aux trois 'e' dans la cible mouton. e{2,} ne correspond pas à l'ensemble, car l'ensemble n'a qu'un seul « e ».

{n}

Cela correspond exactement à n répétitions consécutives d'un caractère ou d'un groupe précédent. Ainsi, la regex, e{2} correspond aux deux 'e' dans la cible, mouton. e{2} ne correspond pas à l'ensemble car l'ensemble n'a qu'un seul « e ». Eh bien, e{2} correspond à deux 'e' dans la cible, mouton. Il y a une nuance ici – voir plus loin.

{n,m}

Cela correspond à plusieurs répétitions consécutives d'un caractère précédent ou d'un groupe précédent, de n à m inclus. Donc, e{1,3} ne correspond à rien dans dig, qui n'a pas de « e ». Il correspond à un 'e' dans l'ensemble, aux deux 'e' en mouton, aux trois 'e' en mouton et trois 'e' en mouton. Il y a une nuance au 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 une chèvre, un lapin ou un cochon. Le code serait le suivant :

carboniserp[] = « La ferme a des porcs de différentes tailles.;

si (recherche_regex(p,expression régulière('chèvre|lapin|cochon')))

cout<< 'correspondant' <<fin;

autre

cout<< 'pas adapté' <<fin;

Le code produit une correspondance. Notez 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 la chèvre, il essaie l'alternative suivante, le lapin. S'il ne réussit pas avec le lapin, il essaie l'alternative suivante, le 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é.

Correspondance du début ou de la fin

Début


Si ^ est au début de l'expression régulière, le texte de début de la chaîne cible peut être mis en correspondance avec l'expression régulière. Dans le code suivant, le début de la cible est abc, qui correspond :

si (recherche_regex('abc et def',expression régulière('^ abc')))

cout<< 'correspondant' <<fin;

Aucune correspondance n'a lieu dans le code suivant :

si (recherche_regex('Oui, abc et def',expression régulière('^ abc')))

cout<< 'correspondant' <<fin;

autre

cout<< 'pas adapté' <<fin;

Ici, abc n'est pas au début de la cible.

Remarque : Le caractère circonflexe, « ^ », est un métacaractère au début de l'expression régulière, correspondant au début de la chaîne cible. C'est toujours un métacaractère au début de la classe de caractères, où il annule la classe.

Finir

Si $ est à la fin de l'expression régulière, le texte de fin de la chaîne cible peut être mis en correspondance avec l'expression régulière. Dans le code suivant, la fin de la cible est xyz, qui correspond :

si (recherche_regex('uvw et xyz',expression régulière('xyz$')))

cout<< 'correspondant' <<fin;

Aucune correspondance n'a lieu dans le code suivant :

si (recherche_regex('uvw et xyz final',expression régulière('xyz$')))

cout<< 'correspondant' <<fin;

autre

cout<< 'pas adapté' <<fin;

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

Regroupement

Les parenthèses peuvent être utilisées pour regrouper des caractères dans un motif. Considérez l'expression régulière suivante :

'un concert (pianiste)'

Le groupe est ici pianiste entouré des métacaractères ( et ). C'est en fait un sous-groupe, alors qu'un concert (pianiste) c'est l'ensemble du groupe. Considérer ce qui suit:

'Le (le pianiste est bon)'

Ici, le sous-groupe ou la sous-chaîne est, le pianiste est bon.

Sous-chaînes avec des parties communes

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

'La bibliothèque a une étagère qui est admirée.';

'Voici le comptable.';

'Le comptable travaille avec l'étagère.';

Supposons que l'intérêt du programmeur n'est pas de savoir laquelle de ces phrases est dans l'ordinateur. Pourtant, son intérêt est de savoir si une étagère ou un comptable est présent dans la chaîne cible de l'ordinateur. Dans ce cas, son regex peut être :

'bibliothèque|comptable.'

Utiliser l'alternance.

Remarquez que le livre, qui est commun aux deux mots, a été tapé deux fois, dans les deux mots du motif. Pour éviter de taper book deux fois, la regex serait mieux écrite comme :

'livre(étagère|gardien)'

Ici, le groupe, étagère|gardienne Le métacaractère d'alternance a toujours été utilisé, 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 une étagère ou un gardien qui vient immédiatement après le livre. La sortie du code suivant est mise en correspondance :

carboniserp[] = « La bibliothèque a une étagère qui est admirée.;

si (recherche_regex(p,expression régulière('livre(étagère|gardien)')))

cout<< 'correspondant' <<fin;

étagère et non comptable ont été appariés.

Les constantes regex_constantes icase et multiligne

icase

La correspondance est sensible à la casse par défaut. Cependant, il peut être rendu insensible à la casse. Pour ce faire, utilisez la constante regex::icase, comme dans le code suivant :

si (recherche_regex('Retour d'information',expression régulière('alimentation',expression régulière::icase)))

cout<< 'correspondant' <<fin;

La sortie est adaptée. Ainsi, les commentaires avec « F » majuscule ont été mis en correspondance avec le flux avec « f » minuscule. regex::icase est devenu le deuxième argument du constructeur regex(). Sans cela, la déclaration ne produirait pas de correspondance.

Multiligne

Considérez le code suivant :

carboniserp[] = 'ligne 1 ligne 2 ligne 3';

si (recherche_regex(p,expression régulière('^. * $')))

cout<< 'correspondant' <<fin;

autre

cout<< 'pas adapté' <<fin;

La sortie ne correspond pas. L'expression régulière, ^.*$, correspond à la chaîne cible de son début à sa fin. .* signifie n'importe quel caractère sauf , zéro ou plusieurs fois. Ainsi, en raison des caractères de nouvelle ligne ( ) dans la cible, il n'y avait pas de correspondance.

La cible est une chaîne multiligne. Pour que '.' corresponde au caractère de nouvelle ligne, la constante regex::multiline doit être créée, le deuxième argument de la construction regex(). Le code suivant illustre cela :

carboniserp[] = 'ligne 1 ligne 2 ligne 3';

si (recherche_regex(p,expression régulière('^. * $',expression régulière::multiligne)))

cout<< 'correspondant' <<fin;

autre

cout<< 'pas adapté' <<fin;

Faire correspondre la chaîne cible entière

Pour faire correspondre l'intégralité de la chaîne cible, qui n'a pas le caractère de nouvelle ligne ( ), la fonction regex_match() peut être utilisée. Cette fonction est différente de regex_search(). Le code suivant illustre cela :

carboniserp[] = 'Premier Deuxième Troisième';

si (regex_match(p,expression régulière('.*seconde.*')))

cout<< 'correspondant' <<fin;

Il y a une correspondance ici. Cependant, notez que l'expression régulière correspond à l'ensemble de la chaîne cible et que la chaîne cible n'a pas de «   ».

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. L'ensemble de la chaîne (partie) correspondante et les sous-chaînes correspondantes peuvent être connues avec. 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 correspondances

Considérez le code suivant :

carboniserp[] = « La femme que vous cherchiez !;

cmatch m;

si (recherche_regex(p,m,expression régulière('w.m.n')))

cout<<m[0] <<fin;

La chaîne cible contient le mot femme. La sortie est woman’, ce qui correspond à la regex, w.m.n. À l'index zéro, le tableau spécial contient la seule correspondance, qui est woman.

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 cela :

cmatch m;

si (recherche_regex(« Le rat, le chat, la chauve-souris !,m,expression régulière('[bcr]à')))

cout<<m[0] <<fin;

cout<<m[1] <<fin;

cout<<m[2] <<fin;

La sortie est rat à partir de l'indice zéro. m[1] et m[2] sont vides.

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

si (recherche_regex(« Le lapin, la chèvre, le cochon !,m,expression régulière('chèvre|lapin|cochon')))

cout<<m[0] <<fin;

cout<<m[1] <<fin;

cout<<m[2] <<fin;

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

Groupements

Lorsque des groupes sont impliqués, le motif complet correspondant est placé dans la cellule zéro du tableau spécial. La prochaine sous-chaîne trouvée va dans la cellule 1 ; la sous-chaîne suivante va dans la cellule 2 ; etc. Le code suivant illustre cela :

si (recherche_regex(« Meilleur libraire aujourd'hui ! »,m,expression régulière('book((sel)(ler))')))

cout<<m[0] <<fin;

cout<<m[1] <<fin;

cout<<m[2] <<fin;

cout<<m[3] <<fin;

La sortie est :

libraire

vendeur

cellule

lire

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

Position du match

La position de match 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 cela :

cmatch m;

si (recherche_regex(« Meilleur libraire aujourd'hui ! »,m,expression régulière('book((sel)(ler))')))

cout<<m[0] << '->' <<m.position(0) <<fin;

cout<<m[1] << '->' <<m.position(1) <<fin;

cout<<m[2] << '->' <<m.position(2) <<fin;

cout<<m[3] << '->' <<m.position(3) <<fin;

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

libraire->5

vendeur->9

cellule->9

lire->12

Rechercher et remplacer

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

#comprendre

#comprendre

#comprendre

en utilisant l'espace de noms std;

entierprincipale()
{
chaîne chaîne= « Tiens, vient mon homme. Voilà ton homme.;
chaîne newStr=regex_replace(p,expression régulière('homme'), 'femme');
cout<<newStr<<fin;

revenir 0;
}

La fonction regex_replace(), telle que codée ici, remplace toutes les correspondances. Le premier argument de la fonction est la cible, le second 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étacaractères. Les fonctions couramment utilisées pour les expressions régulières C++ sont : regex_search(), regex_match() et regex_replace(). Une expression régulière est un motif entre guillemets doubles. Cependant, ces fonctions prennent l'objet regex comme argument et pas seulement la regex. La regex doit être transformée en un objet regex avant que ces fonctions ne puissent l'utiliser.