Pourquoi la première instruction d'impression ne génère-t-elle pas ce que j'attends: puisque les deux * et + sont gourmands, pourquoi l'intérieur * est-à-dire à l'intérieur de "((" dans le Premier match ne consommant pas la chaîne entière? p> use strict;
use warnings;
my $string = "This is a test string";
$string =~ /((.*)*)/;
print "first = $1, sec = $2\n"; #prints "first = This is a test string, sec ="
$string =~ /((.+)*)/;
print "first = $1, sec = $2\n"; #prints "first = This is a test string, sec = This is a test string"
4 Réponses :
dans la première regex Cela ne se produit pas avec l'autre regex car Edit: sur ce qui se passe où: 2 $ contiendra ce qui correspond à la dernière fois . * code> est apparié deux fois. La première fois qu'il correspond à la chaîne entière. La deuxième fois qu'il correspond à la chaîne vide à la fin, car
. * Code> correspond à la chaîne vide quand il n'y a rien d'autre à correspondre. P>
. + code> ne peut pas correspondre à la chaîne vide. P>
. * code> /
. + code> sont appliqués. 1 $ contiendra ce qui est assorti par
(. *) * Code> /
(. +) * Code>, c'est-à-dire la chaîne entière. P>
Droit. Mais comme les crochets entourent la corde - je m'attendrais à ce que tout le monde à l'intérieur des supports soit 2 $ (et pas seulement le *)
Alors, d'où finit le match extérieur ()? De votre description, je aurais deviné 3 $, mais cela n'y est pas allé.
Les groupes @anna sont comptés par la parenthèse d'ouverture, de sorte que 1 $ est la chaîne entière, où 2 $ est l'ensemble intérieur des parenthèses.
La correspondance interne est en fait 2 $ code>, l'extérieur est
1 $ code>. Lorsque la partie interne correspond à une seconde fois, elle "écrase" la sortie capturée à partir de la première fois qu'elle appartenait. Si l'intérieur
(. *) Code> correspond à plusieurs reprises, seule la dernière correspondance est préservée comme
2 $ code>.
@ Sepp2k, puisque la correspondance REGEX commence à partir de l'intérieur *, il doit consommer toute la chaîne. Alors, pourquoi 2 $ est vide dans le premier cas?
Parce qu'après correspondance de la chaîne entière, elle peut toujours correspondre à la chaîne vide. Vous pouvez toujours correspondre à la chaîne vide. Il y en a partout.
Utiliser avec " p> p> p> p > p> p> Utilisez RE 'Débogou' code> < / a> "Résultats dans:
Voir "Perldoc Re" ou perdoc.perl.org/re.html, qui vous mène à "Perldoc Perldebug" et à perdoc.perl.org/perldebug.html#debugging-regular-expression s .
@Brad & Ether: Oui, je vais être honnête, j'aimerais être plus cool et j'ai compris que la production, mais je peux à peine le suivre. Le lien des points d'éther pour le dire, à quoi je peux dire seulement, AMEN: "Pour comprendre cette sortie typiquement volumineuse, il ne faut pas seulement avoir une idée de la manière dont les travaux d'expression d'expression régulière en général, mais savent également comment les expressions régulières de Perl sont compilés internes dans un automate. "
Ce serait une meilleure réponse s'il s'agissait d'un commentaire sur ce que nous sommes censés remarquer sur ces deux sorties.
J'ai souligné les différences, espérons-le, il est plus facile de comprendre.
Le problème avec la première regex est une combinaison du fait que () * code> enregistre uniquement le dernier match et
. * code> correspond à une chaîne vide (c'est-à-dire rien). Donc, donné
1 $ code> sera
"b" code>. Si vous combinez ce comportement avec le fait que
. * Code> correspond à une chaîne vide, vous pouvez voir qu'il existe deux correspondances de la capture intérieure: "Ceci est une chaîne de test" et "". Puisque la chaîne vide est venue en dernier, il est enregistré sur
2 $ code>.
1 $ code> est l'ensemble de la capture, il est donc équivalent à
"Ceci est une chaîne de test". "" code>. Le second cas fonctionne comme vous vous attendez à ce que ce soit parce que
. + Code> ne correspondra pas à une chaîne vide. P> p>
Je n'ai pas de réponse, mais j'ai une façon différente de cadrager la question, en utilisant des expressions régulières plus simples et peut-être plus réalistes.
Les deux premiers exemples se comportent exactement comme je m'attends à: Beaucoup de réponses ont souligné que Mise à jour après les commentaires utiles de Chas . Owens fort>. La première évaluation de l'un des trois exemples aboutit à . * / Code> Consume la chaîne entière et l'expression régulière renvoie une liste avec un seul élément. Mais la troisième expression régulière renvoie une liste avec 2 éléments. P>
. * Code> correspondra à n'importe quoi. Bien que ce soit vrai, cette réponse ne va pas au cœur de la matière, qui est-ce: pourquoi le moteur d'expression régulier est-il toujours à la chasser après
. * Code> a consommé toute la chaîne? Dans d'autres circonstances (telles que les deux premiers exemples),
. * Code> ne jette pas dans une chaîne vide supplémentaire pour une bonne mesure. P>
. * Code> correspondant à la chaîne entière. Si nous pouvions intervenir et appeler
POS () code> à ce moment-là, le moteur serait effectivement à la fin de la chaîne (au moins comme nous percevrions la chaîne; voir les commentaires de Chas. Pour plus de perspicacité cette). Cependant, l'option
/ g code> indique à Perl d'essayer de faire correspondre à nouveau à nouveau la em> Regex. Cette deuxième tentative échouera pour des exemples n ° 1 et n ° 2 et que l'échec provoquera le moteur d'arrêter de chasser. Cependant, avec Regex n ° 3, le moteur recevra une autre correspondance: une chaîne vide. Ensuite, l'option
/ g code> indique au moteur d'essayer à nouveau tout le motif. Maintenant, il n'y a vraiment rien de gauche pour correspondre - ni caractères réguliers ni la chaîne vide de fin - le processus s'arrête. P> p>
Imaginez que vous êtes le moteur de regex. On vous a demandé de faire correspondre n'importe quoi, alors vous commencez à "F", vous voyez que vous pouvez ajouter "O" et toujours faire correspondre, vous voyez que vous pouvez ajouter "O" et toujours correspondre, il n'y a plus de caractères à correspondre. Vous complétez la correspondance, l'option G vous permet de voir s'il existe une autre correspondance après la première, de sorte que vous regardez la chaîne vide qui reste. La chaîne vide correspond, de sorte que vous le retournez, puis arrêtez-vous.
@Chas. Je suis probablement dense, mais pourquoi l'option / g code> a-t-elle le même effet sur les deux premiers exemples?
Oui, mais parce que le premier exemple est ancré au début de la chaîne, la chaîne vide à l'extrémité ne peut pas correspondre (et n'est donc pas retournée). Dans le second cas, la correspondance nécessite l'existence d'au moins un caractère dans la correspondance. Il ne peut donc pas correspondre à une chaîne vide.
Les matchs zéro ou davantage sans échec sont généralement déroutants jusqu'à ce que vous obtenez la suspension d'eux: perl -le 'imprimer pour "ababa" = ~ / a * / g' code>, nous obtenons ici six matchs, un Pour le premier A, alors un autre pour la chaîne vide entre le A et le b. Puis la seconde a, puis une autre chaîne vide. Enfin, il correspondra au troisième A, puis la chaîne vide entre l'A et la fin de la chaîne. C'est pourquoi il s'agit généralement d'une mauvaise idée d'avoir des matchs à zéro ou davantage sans échec.
La raison pour laquelle nous avons besoin du comportement de la chaîne de correspondance est plus évidente lorsque nous examinons "aa" = ~ /a.*a / code>. Pour que cela correspond à cela, le premier A doit correspondre au premier A, le second A doit correspondre à la seconde A, et le
* code> doit correspondre à la chaîne vide entre eux. Une chaîne (comme on le voit par le moteur Regex) n'est vraiment qu'une liste de caractères séparés par des chaînes vides et la regex
/ ab / code> correspond à un a suivi d'une chaîne vide, suivie d'un b.
@Chas. Merci, cela aide beaucoup.
Une chaîne vide ne peut toujours être consommée qu'une fois. Donc, il correspond à la fin de la chaîne, correspond à l'extrémité de la chaîne vide de la chaîne, puis il n'y a plus rien à correspondre pour que cela s'arrête.
La meilleure question est "pourquoi tu fais ça?" :) Est-ce juste parce que vous êtes curieux de ce cas de bord étrange, ou essayez-vous de l'utiliser réellement?
Brian, j'étais juste curieux. :-)