web-dev-qa-db-fra.com

Quelle est la différence entre $ / et $ ¢ en regex?

Comme le titre l'indique, quelle est la différence entre $/ et ? Ils semblent avoir toujours la même valeur:

my $text = "Hello world";

$text ~~ /(\w+) { say $/.raku } (\w+)/;
$text ~~ /(\w+) { say $¢.raku } (\w+)/;

Les deux aboutissent à des objets Match avec les mêmes valeurs. Quelle est la logique d'utiliser l'un sur l'autre?

13
user0721090601

La variable $/ fait référence à la correspondance la plus récente tandis que la variable fait référence à la correspondance la plus récente. Dans la plupart des expressions rationnelles de base comme ci-dessus, cela peut être une seule et même chose. Mais comme on peut le voir à partir de la sortie du .raku méthode, les objets Match peuvent contenir d'autres objets Match (c'est ce que vous obtenez lorsque vous utilisez $<foo> ou $1 pour les captures).

Supposons à la place que nous ayons la regex suivante avec une capture quantifiée

/ ab (cd { say $¢.from, " ", $¢.to } ) + /

Et exécuté, il verrait la sortie suivante si nous correspondions à "abcdcdcd":

0 2
0 4
0 6

Mais si nous changeons d'utiliser à $/, nous obtenons un résultat différent:

2 2
4 4
6 6

(La raison pour laquelle le .to semble être un peu bizarre, c'est que - et .pos— ne sont pas mis à jour avant la fin du bloc de capture.)

En d'autres termes, va toujours faire référence à ce qui sera votre objet de correspondance final (c'est-à-dire $final = $text ~~ $regex) afin que vous puissiez parcourir une arborescence de capture complexe à l'intérieur de l'expression régulière exactement comme vous le feriez après avoir terminé la correspondance complète Donc, dans l'exemple ci-dessus, vous pouvez simplement faire $¢[0] pour faire référence à la première correspondance, $¢[1] le second, etc.

À l'intérieur d'un bloc de code regex, $/ fera référence à la correspondance la plus immédiate. Dans le cas ci-dessus, c'est la correspondance pour l'intérieur du ( ) et ne connaîtra pas les autres correspondances, ni le début original de la correspondance: juste le début pour le ( ) bloquer. Alors donnez une regex plus complexe:

/ a $<foo>=(b $<bar>=(c)+ )+ d /

Nous pouvons accéder à tout moment en utilisant $ ¢ tous les jetons foo en disant $¢<foo>. Nous pouvons accéder aux jetons bar d'un foo donné en utilisant $¢<foo>[0]<bar>. Si nous insérons un bloc de code à l'intérieur de la capture de foo, il pourra accéder aux jetons bar en utilisant $<bar> ou $/<bar>, mais il ne pourra pas accéder aux autres foos.

13
user0721090601