Apprentissage d'expressions régulières [fermé]

166

Je ne comprends pas vraiment les expressions régulières. Pouvez-vous me les expliquer d'une manière facile à suivre? S'il existe des outils ou des livres en ligne, pourriez-vous également créer un lien vers eux?

Teifion
la source

Réponses:

789

La partie la plus importante est les concepts. Une fois que vous avez compris le fonctionnement des blocs de construction, les différences de syntaxe ne représentent guère plus que des dialectes doux. Une couche au-dessus de la syntaxe de votre moteur d'expression régulière est la syntaxe du langage de programmation que vous utilisez. Les langages tels que Perl suppriment la plupart de cette complication, mais vous devrez garder à l'esprit d'autres considérations si vous utilisez des expressions régulières dans un programme C.

Si vous considérez les expressions régulières comme des blocs de construction que vous pouvez mélanger et associer à votre guise, cela vous aide à apprendre à écrire et à déboguer vos propres modèles, mais aussi à comprendre les modèles écrits par d'autres.

Commencez simplement

Conceptuellement, les expressions régulières les plus simples sont des caractères littéraux. Le motif Ncorrespond au caractère «N».

Les expressions régulières les unes à côté des autres correspondent aux séquences. Par exemple, le motifNick correspond à la séquence «N» suivie de «i» suivi de «c» suivi de «k».

Si vous avez déjà utilisé grepsous Unix - ne serait-ce que pour rechercher des chaînes d'apparence ordinaire - vous avez déjà utilisé des expressions régulières! (Le rein grepfait référence aux expressions régulières.)

Commander dans le menu

En ajoutant juste un peu de complexité, vous pouvez faire correspondre «Nick» ou «nick» avec le motif [Nn]ick. La partie entre crochets est une classe de caractères , ce qui signifie qu'elle correspond exactement à l'un des caractères inclus. Vous pouvez également utiliser des plages dans les classes de caractères.[a-c] correspond à «a» ou «b» ou «c».

Le motif .est spécial: plutôt que de correspondre à un point littéral uniquement, il correspond à n'importe quel caractère . C'est le même concept que la très grande classe de personnages [-.?+%$A-Za-z0-9...].

Considérez les classes de caractères comme des menus: choisissez-en un seul.

Raccourcis utiles

L'utilisation .peut vous faire économiser beaucoup de saisie et il existe d'autres raccourcis pour les modèles courants. Disons que vous voulez faire correspondre un chiffre: une façon d'écrire c'est [0-9]. Les chiffres sont une cible de correspondance fréquente, vous pouvez donc utiliser le raccourci à la place \d. D'autres sont \s(espaces) et \w(caractères de mot: alphanumériques ou trait de soulignement).

Les variantes en majuscules sont leurs compléments, donc \Scorrespond à n'importe quel caractère non- blanc, par exemple.

Une fois ne suffit pas

À partir de là, vous pouvez répéter des parties de votre motif avec des quantificateurs . Par exemple, le modèle ab?ccorrespond à «abc» ou «ac» car le ?quantificateur rend le sous-modèle qu'il modifie facultatif. D'autres quantificateurs sont

  • * (zéro fois ou plus)
  • + (une ou plusieurs fois)
  • {n}(exactement n fois)
  • {n,}(au moins n fois)
  • {n,m}(au moins n fois mais pas plus de m fois)

En rassemblant certains de ces blocs, le motif [Nn]*ickcorrespond à tous

  • méchant
  • pseudo
  • pseudo
  • Nnick
  • nNick
  • Nick
  • (etc)

Le premier match démontre une leçon importante: *réussit toujours!Tout motif peut correspondre à zéro fois.

Quelques autres exemples utiles:

  • [0-9]+(et son équivalent \d+) correspond à tout entier non négatif
  • \d{4}-\d{2}-\d{2} correspond aux dates au format 01/01/2019

Regroupement

Un quantificateur modifie le motif à sa gauche immédiate. Vous pouvez vous attendre 0abc+0à correspondre à «0abc0», «0abcabc0», et ainsi de suite, mais le modèle immédiatement à gauche du quantificateur plus est c. Cela signifie 0abc+0correspond à «0abc0», «0abcc0», «0abccc0», etc.

Pour faire correspondre une ou plusieurs séquences de 'abc' avec des zéros aux extrémités, utilisez 0(abc)+0. Les parenthèses désignent un sous-modèle qui peut être quantifié comme une unité. Il est également courant que les moteurs d'expressions régulières enregistrent ou «capturent» la partie du texte d'entrée qui correspond à un groupe entre parenthèses. Extraire des bits de cette manière est beaucoup plus flexible et moins sujet aux erreurs que de compter les indices etsubstr .

Alternance

Plus tôt, nous avons vu une façon de faire correspondre soit «Nick» ou «nick». Un autre est avec alternance comme dans Nick|nick. N'oubliez pas que l'alternance comprend tout à sa gauche et tout à sa droite. Utilisez le regroupement entre parenthèses pour limiter la portée de |, par exemple , (Nick|nick).

Pour un autre exemple, vous pouvez écrire de [a-c]manière équivalente a|b|c, mais cela risque d'être sous-optimal car de nombreuses implémentations supposent que les alternatives auront des longueurs supérieures à 1.

S'échapper

Bien que certains caractères se correspondent, d'autres ont des significations spéciales. Le modèle \d+ne correspond pas à la barre oblique inverse suivie d'un D minuscule suivi d'un signe plus: pour obtenir cela, nous utiliserions \\d\+. Une barre oblique inverse supprime la signification spéciale du caractère suivant.

Cupidité

Les quantificateurs d'expression régulière sont gourmands. Cela signifie qu'ils correspondent à autant de texte que possible tout en permettant à l'ensemble du modèle de correspondre avec succès.

Par exemple, disons que l'entrée est

"Bonjour," dit-elle, "Comment vas-tu?"

Vous pourriez vous attendre ".+" à correspondre uniquement à «Bonjour», et serez alors surpris de voir qu'il correspond à «Bonjour» tout au long de «vous?».

Pour passer de gourmand à ce que vous pourriez considérer comme prudent, ajoutez un supplément ?au quantificateur. Vous comprenez maintenant comment fonctionne \((.+?)\)l'exemple de votre question. Il correspond à la séquence d'une parenthèse gauche littérale, suivie d'un ou plusieurs caractères et terminée par une parenthèse droite.

Si votre entrée est «(123) (456)», la première capture sera «123». Les quantificateurs non gourmands veulent permettre au reste du modèle de commencer à correspondre dès que possible.

(Quant à votre confusion, je ne connais aucun dialecte d'expression régulière où ((.+?))ferait la même chose. Je soupçonne que quelque chose s'est perdu dans la transmission quelque part en cours de route.)

Ancres

Utilisez le modèle spécial ^pour correspondre uniquement au début de votre entrée et $pour correspondre uniquement à la fin. Faire des «serre-livres» avec vos motifs où vous dites: «Je sais ce qu'il y a à l'avant et à l'arrière, mais donnez-moi tout ce qui se trouve entre» est une technique utile.

Dites que vous souhaitez faire correspondre les commentaires du formulaire

-- This is a comment --

vous écririez ^--\s+(.+)\s+--$.

Construit le tien

Les expressions régulières sont récursives, donc maintenant que vous comprenez ces règles de base, vous pouvez les combiner comme vous le souhaitez.

Outils d'écriture et de débogage des expressions régulières:

Livres

Ressources gratuites

note de bas de page

†: L'énoncé ci-dessus qui .correspond à n'importe quel caractère est une simplification à des fins pédagogiques qui n'est pas strictement vraie. Le point correspond à n'importe quel caractère sauf le saut de ligne, "\n"mais dans la pratique, vous vous attendez rarement à un motif tel que .+le franchissement d'une limite de nouvelle ligne. Les expressions rationnelles Perl ont un /scommutateur et Java Pattern.DOTALL, par exemple, pour faire .correspondre n'importe quel caractère. Pour les langues qui n'ont pas une telle fonctionnalité, vous pouvez utiliser quelque chose comme [\s\S]pour faire correspondre "n'importe quel espace ou tout autre espace", en d'autres termes n'importe quoi.

Greg Bacon
la source
14
Vous pouvez également utiliser la méthode d'essai et d'erreur et que suivre le testeur et le débogueur de regex en ligne peut être d'une grande aide: regex101.com
Juraj.Lorinc
2
Il convient de mentionner que, bien qu'il s'agisse d'un modèle similaire, ce a{,m}n'est pas une chose, du moins en Javascript, Perl et Python.
Fund Monica's Lawsuit
2
Il serait très intéressant de mentionner qu'il existe différents types de moteurs d'expressions régulières avec tous des ensembles de fonctionnalités et des règles syntaxiques différents.
hek2mgl
1
hackr.io/tutorials/learn-regular-expressions-regex est un excellent endroit pour trouver les meilleurs didacticiels de regex en ligne. Tous les tutoriels ici sont soumis et recommandés (votés comme SO) par la communauté de programmation.
Saurabh Hooda
2
Appréciez vos efforts pour tout apporter ici en un mot.
Saurabh Tiwari