6
votes

Le quantificateur de regex non gourmands donne un résultat gourmand

J'ai une .NET REGEX que je passe à l'aide de Windows PowerShell. La sortie est la suivante:

> [System.Text.RegularExpressions.Regex]::Match("aaa aaa bbb", "aaa.*?bbb")


Groups   : {aaa aaa bbb}
Success  : True
Captures : {aaa aaa bbb}
Index    : 0
Length   : 11
Value    : aaa aaa bbb


0 commentaires

4 Réponses :


5
votes

Comparer le résultat de la chaîne AAA AAA BBB BBB CODE>:

regex: aaa.*?bbb 
result: aaa aaa bbb

regex: aaa.*bbb
result: aaa aaa bbb bbb


1 commentaires

C'est l'explication la plus rapide de ce qui se passe. +1



0
votes

Eh bien c'est vraiment simple, nous avons la chaîne suivante

AAA AAA BBB

Voyons que nous avons cette regex aaa. *? BBB . Le moteur Regex commencera par aaa

AAA AAA BBB

Le moteur Regex a maintenant . *? BBB . Il procédera à l'espace

aaa espace AAA BBB

Mais nous avons toujours des caractères jusqu'à ce que BBB ? Donc, le moteur REGEX continuera de la manière et correspond à la deuxième série d'un

aaa espace AAA BBB

Enfin, le moteur Regex correspondra à BBB :

aaa aaa BBB


Voyons donc, si nous voulons seulement faire correspondre la seconde aaa , nous pourrions utiliser la regex suivante:

(? , cela signifie correspondre à AAA qui n'est pas au début de la phrase.

Nous pouvons également utiliser aaa (? = BBB). *? BBB , cela signifie correspondant à aaa suivi de espace BBB .

Voir le fonctionnement 1 - 2 .

vient de venir à mes sens, mais pourquoi n'utilisez-vous pas directement aaa bbb ?


0 commentaires

1
votes

Ce n'est pas un problème gourmand / paresseux. Le problème vient au fait que votre chaîne est analysée de gauche à droite. Lorsque le premier aaa est apparié, le moteur Regex ajoutez des caractères un par un pour avoir le motif complet.

Notez qu'avec un comportement gourmand, dans votre exemple, vous obtenez le même résultat: le premier AAA est assorti, le moteur Regex Prenez tous les derniers caractères et caractères en arrière par caractère jusqu'à ce que le personnage soit terminé. match.


0 commentaires

5
votes

Ceci est un malentendu courant. Les quantificats paresseux ne garantissent pas le match le plus court possible. Ils ne garantissent que le quantificateur actuel, de la position actuelle, ne correspond pas à plus de caractères que nécessaire pour une correspondance globale.

Si vous voulez vraiment assurer la correspondance la plus courte possible, vous devez apporter cela explicite. Dans ce cas, cela signifie qu'au lieu de . *? , vous voulez un sous-crégex qui correspond à tout ce qui n'est ni AAA ni BBB . La regex résultante sera donc xxx


1 commentaires

Je viens de faire ce que j'aurais dû faire en premier lieu et j'ai consulté le chapitre correspondant de Friedl. Cela m'a conduit à AAA ((?! AAA).) * BBB , qui est plus ou moins ce que vous avez dit, sauf que votre réponse a les détails ajoutés de la non-capture de la subexpression et des tests Pour BBB dans le regard négatif. Bonne réponse.