next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Ambito Automático Sup: Introducción Ant: Tablas de Escapes, Metacarácteres, Err: Si hallas una errata ...

Subsecciones



Variables especiales después de un emparejamiento

Despues de un emparejamiento con éxito, las siguientes variables especiales quedan definidas:



$& El texto que casó
$` El texto que está a la izquierda de lo que casó
$' El texto que está a la derecha de lo que casó
$1, $2, $3, etc. Los textos capturados por los paréntesis
$+ Una copia del $1, $2, ...con número mas alto
@- Desplazamientos de las subcadenas que casan en $1 ...
@+ Desplazamientos de los finales de las subcadenas en $1 ...
$#- El índice del último paréntesis que casó
$#+ El índice del último paréntesis en la última expresión regular

Las Variables de match, pre-match y post-mach



Ejemplo:

   1 #!/usr/bin/perl -w
   2 if ("Hello there, neighbor" =~ /\s(\w+),/) {
   3   print "That was: ($`)($&)($').\n",
   4 }

> matchvariables.pl
That was: (Hello)( there,)( neighbor).

El uso de estas variables tenía un efecto negativo en el rendimiento de la regexp. Véase perlfaq6 la sección Why does using $&, $`, or $' slow my program down?.

Once Perl sees that you need one of these variables anywhere in the program, it provides them on each and every pattern match. That means that on every pattern match the entire string will be copied, part of it to $`, part to $&, and part to $'. Thus the penalty is most severe with long strings and patterns that match often. Avoid $&, $', and $` if you can, but if you can't, once you've used them at all, use them at will because you've already paid the price. Remember that some algorithms really appreciate them. As of the 5.005 release, the $& variable is no longer "expensive" the way the other two are.

Since Perl 5.6.1 the special variables @- and @+ can functionally replace $`, $& and $'. These arrays contain pointers to the beginning and end of each match (see perlvar for the full story), so they give you essentially the same information, but without the risk of excessive string copying.

Perl 5.10 added three specials, ${^MATCH}, ${^PREMATCH}, and ${^POSTMATCH} to do the same job but without the global performance penalty. Perl 5.10 only sets these variables if you compile or execute the regular expression with the /p modifier.

pl@nereida:~/Lperltesting$ cat ampersandoldway.pl
#!/usr/local/lib/perl/5.10.1/bin//perl5.10.1 -w
use strict;
use Benchmark qw(cmpthese timethese);

'hola juan' =~ /ju/;
my ($a, $b, $c) = ($`, $&, $');


cmpthese( -1, {
    oldway => sub { 'hola juan' =~ /ju/  },
});
pl@nereida:~/Lperltesting$ cat ampersandnewway.pl
#!/usr/local/lib/perl/5.10.1/bin//perl5.10.1 -w
use strict;
use Benchmark qw(cmpthese timethese);

'hola juan' =~ /ju/p;
my ($a, $b, $c) = (${^PREMATCH}, ${^MATCH}, ${^POSTMATCH});


cmpthese( -1, {
    newway => sub { 'hola juan' =~ /ju/  },
});

pl@nereida:~/Lperltesting$ time ./ampersandoldway.pl
            Rate oldway
oldway 2991861/s     --

real    0m3.761s
user    0m3.740s
sys     0m0.020s
pl@nereida:~/Lperltesting$ time ./ampersandnewway.pl
            Rate newway
newway 8191999/s     --

real    0m6.721s
user    0m6.704s
sys     0m0.016s

Véase

Texto Asociado con el Último Paréntesis

La variable $+ contiene el texto que casó con el último paréntesis en el patrón. Esto es útil en situaciones en las cuáles una de un conjunto de alternativas casa, pero no sabemos cuál:

  DB<9> "Revision: 4.5" =~ /Version: (.*)|Revision: (.*)/ && ($rev = $+);
  DB<10> x $rev
0  4.5
  DB<11> "Version: 4.5" =~ /Version: (.*)|Revision: (.*)/ && ($rev = $+);
  DB<12> x $rev
0  4.5

Los Offsets de los Inicios de los Casamientos: @-

El vector @- contiene los offsets o desplazamientos de los casamientos en la última expresión regular. La entrada $-[0] es el desplazamiento del último casamiento con éxito y $-[n] es el desplazamiento de la subcadena que casa con el n-ésimo paréntesis (o undef si el párentesis no casó). Por ejemplo:

#           012345678
DB<1> $z = "hola13.47"
DB<2> if ($z =~ m{a(\d+)(\.(\d+))?}) { print "@-\n"; }
3 4 6 7
El resultado se interpreta como sigue:

Esto es lo que dice perlvar sobre @-:

This array holds the offsets of the beginnings of the last successful submatches in the currently active dynamic scope. $-[0] is the offset into the string of the beginning of the entire match. The nth element of this array holds the offset of the nth submatch, so $-[1] is the offset where $1 begins, $-[2] the offset where $2 begins, and so on.

After a match against some variable $var:

    $` is the same as substr($var, 0, $-[0])
    $& is the same as substr($var, $-[0], $+[0] - $-[0])
    $' is the same as substr($var, $+[0])
    $1 is the same as substr($var, $-[1], $+[1] - $-[1])
    $2 is the same as substr($var, $-[2], $+[2] - $-[2])
    $3 is the same as substr($var, $-[3], $+[3] - $-[3])

Desplazamientos de los Finales de los Emparejamientos: @+

El array @+ contiene los desplazamientos de los finales de los emparejamientos. La entrada $+[0] contiene el desplazamiento del final de la cadena del emparejamiento completo. Siguiendo con el ejemplo anterior:

#            0123456789
DB<17> $z = "hola13.47x"
DB<18> if ($z =~ m{a(\d+)(\.)(\d+)?}) { print "@+\n"; }
9 6 7 9
El resultado se interpreta como sigue:

Número de paréntesis en la última regexp con éxito

Se puede usar $#+ para determinar cuantos parentesis había en el último emparejamiento que tuvo éxito.

  DB<29> $z = "h"
  DB<30> print "$#+\n" if ($z =~ m{(a)(b)}) || ($z =~ m{(h)(.)?(.)?})
3
  DB<31> $z = "ab"
  DB<32> print "$#+\n" if ($z =~ m{(a)(b)}) || ($z =~ m{(h)(.)?(.)?})
2

Indice del Ultimo Paréntesis

La variable $#- contiene el índice del último paréntesis que casó. Observe la siguiente ejecución con el depurador:

  DB<1> $x = '13.47'; $y = '125'
  DB<2> if ($y =~ m{(\d+)(\.(\d+))?}) { print "last par = $#-, content = $+\n"; }
last par = 1, content = 125
  DB<3> if ($x =~ m{(\d+)(\.(\d+))?}) { print "last par = $#-, content = $+\n"; }
last par = 3, content = 47

@- y @+ no tienen que tener el mismo tamaño

En general no puede asumirse que @- y @+ sean del mismo tamaño.

  DB<1> "a" =~ /(a)|(b)/; @a = @-; @b = @+
  DB<2> x @a
0  0
1  0
  DB<3> x @b
0  1
1  1
2  undef

Véase También

Para saber más sobre las variables especiales disponibles consulte


next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Ambito Automático Sup: Introducción Ant: Tablas de Escapes, Metacarácteres, Err: Si hallas una errata ...
Casiano Rodríguez León
2012-05-22