Les expressions régulières sont essentiellement utilisées pour traiter des chaînes, et il est très pratique de les utiliser pour faire correspondre, extraire et remplacer des chaînes.
Cependant, l'apprentissage des expressions régulières est encore quelque peu difficile. Des concepts tels que la correspondance gourmande, la correspondance non gourmande, la capture de sous-groupes et les sous-groupes non capturants sont non seulement difficiles à comprendre pour les débutants, mais aussi pour de nombreuses personnes qui travaillent depuis plusieurs années.
Alors, quelle est la meilleure façon d’apprendre les expressions régulières ? Comment maîtriser rapidement les expressions régulières ?
Je recommande une façon d'apprendre des règles régulières que je trouve très bonne : l'apprentissage via AST .
Le principe de correspondance des expressions régulières consiste à analyser la chaîne de modèle en AST, puis à utiliser cet AST pour faire correspondre la chaîne cible.
Diverses informations contenues dans la chaîne de modèle seront stockées dans l'AST après l'analyse. AST est un arbre de syntaxe abstraite. Comme son nom l'indique, c'est un arbre organisé selon une structure grammaticale. A partir de la structure d'AST, vous pouvez facilement connaître la syntaxe supportée par les expressions régulières.
Comment visualiser l'AST d'une expression régulière ?
Vous pouvez le visualiser visuellement via le site astexplorer.net :
En basculant le langage d'analyse vers RegExp, vous pouvez visualiser l'AST des expressions régulières.
Comme mentionné précédemment, AST est un arbre organisé selon la grammaire, de sorte que diverses grammaires peuvent être facilement triées à partir de sa structure.
Apprenons ensuite différentes syntaxes du point de vue d'AST :
Commençons par la plus simple /abc/ Un tel régulier peut correspondre à la chaîne de 'abc', et son AST est comme ceci :
3 Char, les valeurs sont respectivement a, b, c, le type est simple. La correspondance ultérieure consiste à parcourir l'AST et à faire correspondre ces trois caractères respectivement.
Nous l'avons testé en utilisant l'API exec :
Le 0ème élément est la chaîne correspondante et index est l'index de départ de la chaîne correspondante. input est la chaîne d’entrée.
Essayons à nouveau les caractères spéciaux :
/ddd/ signifie que correspondre à trois nombres d est un métacaractère (méta-caractère) avec une signification particulière prise en charge par les expressions régulières.
On peut aussi voir à travers AST que bien qu'ils soient aussi Char, leur type est bien méta :
N'importe quel nombre peut être recherché à l'aide du métacaractère d :
Les caractères méta et les caractères simples peuvent être vus d'un seul coup d'œil via AST.
Regular prend en charge la spécification d'un ensemble de caractères via [], ce qui signifie qu'il peut correspondre à n'importe lequel des caractères.
Nous pouvons également voir sur AST qu'il est enveloppé dans une couche de CharacterClass, ce qui signifie classe de caractères, c'est-à-dire qu'il peut correspondre à n'importe quel caractère qu'il contient.
C'est effectivement le cas testé :
Les expressions régulières prennent en charge la spécification du nombre de fois qu'un certain caractère est répété, en utilisant la forme {from,to},
par exemple, /b{1,3}/ signifie que le caractère b est répété 1 à 3 fois. , /[abc ]{1,3}/ signifie que cette classe de caractères a/b/c est répétée 1 à 3 fois.
Comme le montre AST, cette syntaxe est appelée Répétition :
Il possède un attribut quantificateur qui représente le quantificateur. Le type ici est une plage de 1 à 3.
Les expressions régulières prennent également en charge les abréviations de certains quantificateurs, telles que + indiquant 1 à un nombre incalculable de fois, * indiquant 0 à un nombre incalculable de fois et ? indiquant 0 ou 1 fois.
Il existe différents types de quantificateurs :
Certains élèves peuvent se demander : que signifie ici l’attribut gourmand ?
Greedy signifie gourmand. Cet attribut indique si cette répétition est une correspondance gourmande ou non.
Si vous ajoutez un ? après le quantificateur, vous constaterez que gourmand devient faux, ce qui signifie passer à une correspondance non gourmande :
Alors, que signifient gourmand et non gourmand ?
Voyons un exemple.
La correspondance de répétition par défaut est gourmande et continuera à correspondre tant que les conditions sont remplies, donc acbac peut être associé ici.
En ajoutant un ? après que le quantificateur passe à non gourmand, et seul le premier sera mis en correspondance :
Il s'agit d'une correspondance gourmande et d'une correspondance non gourmande. Grâce à AST, nous pouvons clairement savoir que les gourmands et les non gourmands sont pour la grammaire répétée. La valeur par défaut est la correspondance gourmande. Ajoutez un ?
L'expression régulièreprend en charge le placement d'une partie de la chaîne correspondante dans un sous-groupe et son renvoi via ().
Jetez un œil à l’AST :
L'AST correspondant est appelé Groupe.
Et vous constaterez qu’il a un attribut de capture, qui est par défaut true :
Qu'est-ce que cela signifie?
C'est la syntaxe pour la capture de sous-groupes.
Si vous ne souhaitez pas capturer de sous-groupes, vous pouvez écrire comme ceci (?:aaa)
Écoutez, la capture est devenue fausse.
Quelle est la différence entre capture et non capture ?
Essayons :
Oh, il s'avère que l'attribut de capture de Group indique s'il faut extraire ou non.
Nous pouvons voir sur l'AST que la capture est destinée aux sous-groupes. La valeur par défaut est capture, ce qui signifie que le contenu du sous-groupe est extrait. Vous pouvez passer en non-capture via ? : et le contenu du sous-groupe ne sera pas extrait.
Nous sommes déjà habitués à utiliser AST pour comprendre la syntaxe régulière, mais regardons quelque chose d'un peu plus difficile :
Les expressions régulières prennent en charge l'expression d'assertions anticipées via la syntaxe de (?=xxx), qui est utilisé pour juger un certain caractère si la chaîne est précédée d'une certaine chaîne.
Grâce à AST, vous pouvez voir que cette syntaxe s'appelle Assertion et que le type est lookahead, ce qui signifie regarder vers l'avant, ne correspondant qu'au sens précédent :
Qu'est-ce que cela signifie? Pourquoi écris-tu ceci ? Quelle est la différence entre /bbb(ccc)/ et /bbb(?:ccc)/?
Essayons :
Cela peut être vu à partir des résultats :
/bbb(ccc)/ correspond au sous-groupe de ccc et extrait ce sous-groupe car le sous-groupe par défaut est capturé.
/bbb(?:ccc)/ correspond au sous-groupe de ccc mais n'est pas extrait car nous avons configuré le sous-groupe pour qu'il ne capture pas via ?:.
/bbb(?=ccc)/ Le sous-groupe correspondant à ccc n'est pas extrait, ce qui indique qu'il n'est pas non plus en capture. La différence entre cela et ? : est que ccc n'apparaît pas dans le résultat correspondant.
C'est la nature d'une assertion anticipée : une assertion anticipée signifie qu'une certaine chaîne est précédée d'une certaine chaîne, le sous-groupe correspondant n'est pas capturant et la chaîne affirmée n'apparaîtra pas dans le résultat correspondant.
S'il n'est pas suivi de cette chaîne, il ne correspondra pas :
Remplacez ?= par ?! Ensuite, la signification change.
Bien que l’assertion d’anticipation soit toujours affirmée en premier, il existe un attribut négatif supplémentaire, vrai.
La signification est évidente. À l'origine, cela signifie que le devant est une certaine chaîne. Après négation, cela signifie que le devant n'est pas une certaine chaîne.
Le résultat de la correspondance est alors exactement le contraire :
Désormais, cela ne correspond que s'il n'y a pas une certaine chaîne devant lui. Il s'agit d'une assertion prospective négative.
S'il y a une assertion précédente, il y aura naturellement une assertion finale, c'est-à-dire qu'elle ne correspondra que si elle est suivie d'une certaine chaîne.
De la même manière, il peut également être refusé :
L'AST correspondant à (?<=aaa) est facile à imaginer, ce qui est une assertion lookbehind :
L'AST correspondant à (?<!aaa) consiste à ajouter un attribut négatif :
L'assertion look-ahead et l'assertion look-behind sont la syntaxe d'expression régulière la plus difficile à comprendre. Est-elle beaucoup plus facile à comprendre si vous l'apprenez via AST ~
les expressions régulières sont un outil très pratique pour traiter les chaînes, mais elles l'est encore un peu. difficile à apprendre. Beaucoup de gens sont confus au sujet de la syntaxe telle que la correspondance gourmande, la correspondance non gourmande, la capture de sous-groupes, les sous-groupes non capturants, les assertions anticipées, les assertions regardées derrière, etc.
Je recommande d'apprendre les règles régulières via AST. AST est un arbre d'objets organisé selon une structure grammaticale. Diverses syntaxes peuvent être facilement clarifiées grâce aux noms et attributs des nœuds AST.
Par exemple, nous avons clarifié via AST :
La syntaxe de répétition (Répétition) est sous la forme d'un caractère + quantificateur. La valeur par défaut est une correspondance gourmande (gourmand est vrai), ce qui signifie une correspondance jusqu'à ce qu'aucune correspondance ne soit ajoutée après que le quantificateur soit passé à non. -correspondance gourmande, s'arrête lorsqu'un caractère correspond.
La syntaxe de sous-groupe (Groupe) est utilisée pour extraire une certaine chaîne. La valeur par défaut est la capture (la capture est vraie), ce qui signifie que l'extraction est requise. Vous pouvez passer à la non-capture via (?:xxx), qui correspond uniquement mais n'extrait pas. .
La syntaxe d'assertion (Assertion) représente une certaine chaîne avant ou après. Elle est divisée en assertion anticipée et assertion apparente. La syntaxe est (?=xxx) et (?<=xxx) respectivement. négation (négatif est vrai), ce qui signifie exactement le contraire.
S'agit-il d'une compréhension approfondie de la syntaxe dans divers documents ou d'une compréhension approfondie de la syntaxe dans le compilateur ?
Pas besoin de demander, ça doit être le compilateur !
Alors il est naturellement préférable d'apprendre la grammaire à travers l'arbre syntaxique analysé selon la grammaire plutôt que le document.
Cela est vrai pour les expressions régulières, mais également pour l'apprentissage d'autres grammaires. Si vous pouvez apprendre la grammaire à l'aide d'AST, vous n'avez pas besoin de lire la documentation.