Usate l'anchor \G per iniziare il prossimo match sulla stessa stringa
dove è finito l'ultimo match. Il motore delle espressioni regolari,
con questa anchor, non può tralasciare alcun carattere per trovare
il prossimo match, dunque \G è analogo all'anchor dell'inzio
di stringa, ^. L'anchor \G viene usato tipicamente con il flag g.
Esso utilizza il valore di pos() per decidere la posizione da cui far partire
il match seguente. Come l'operatore di match che esegue match consecutivi,
esso aggiorna pos() con la posizione del successivo carattere dopo l'ultimo
match (oppure il primo carattere del match successivo, dipende da come
preferite vedere la cosa). Ogni stringa ha il proprio valore di pos().
Supponiamo vogliate fare un match di coppie consecutive di cifre in una
stringa come "1122a4" e finire di cercare quando trovate caratteri che
non sono cifre. Volete trovare 11 e 22 ma la lettera <a> appare
tra 22 e 44 e volete fermarvi alla a. Una semplice ricerca delle
coppie di cifre salta la a e trova 44.
$_ = "1122a44";
my @coppie = m/(\d\d)/g; # qw( 11 22 44 )
Se utilizzate l'anchor \G, forzate la ricerca dopo 22 ad iniziare dalla
a. L'espressione regolare non può effettuare alcun match
lì, poiché non trova una cifra, e dunque la ricerca
successiva fallisce e l'operatore di matching ritorna le coppie che
ha trovato in precedenza.
$_ = "1122a44";
my @coppie = m/\G(\d\d)/g; # qw( 11 22 )
Potete anche usare l'anchor \G in un contesto scalare. Avete
ugualmente bisogno del flag g.
$_ = "1122a44";
while( m/\G(\d\d)/g )
{
print "Trovato $1\n";
}
Dopo che il match fallisce alla lettera C<a>, il perl reinizializza pos()
ed il successivo match sulla stessa stringa parte all'inizio.
$_ = "1122a44";
while( m/\G(\d\d)/g )
{
print "Trovato $1\n";
}
print "Trovato $1 dopo il while" if m/(\d\d)/g; # trova "11"
Potete disabilitare il reinizializzarsi di pos() in caso di fallimento
utilizzando il flag c. Match successivi iniziano dove finisce l'ultimo
match che ha avuto successo (il valore di pos()) anche se nel frattempo
è fallito un match sulla stessa stringa. In questo caso, il match
dopo il ciclo while() inizia alla a (dove si è fermato l'ultimo
match) e poiché non usa alcuna anchor, può tralasciare
la a per trovare "44".
$_ = "1122a44";
while( m/\G(\d\d)/gc )
{
print "Trovato $1\n";
}
print "Trovato $1 dopo il while" if m/(\d\d)/g; # trova "44"
Tipicamente si usa l'anchor \G con il flag c quando si vuole tentare
un match differente se ne fallisce uno, come in un analizzatore lessicale.
Jeffrey Friedl offre questo esempio che funziona sul 5.004 o successivi.
while (<>) {
chomp;
ANALIZZATORE_SINTATTICO: {
m/ \G( \d+\b )/gcx && do { print "numero: $1\n"; redo; };
m/ \G( \w+ )/gcx && do { print "parola: $1\n"; redo; };
m/ \G( \s+ )/gcx && do { print "spazio: $1\n"; redo; };
m/ \G( [^\w\d]+ )/gcx && do { print "altro: $1\n"; redo; };
}
}
Per ogni linea, il ciclo dell'ANALIZZATORE_SINTATTICO prima cerca di
effettuare il match di una serie di cifre seguite da un confine di parola.
Questo match deve iniziare alla posizione dove l'ultimo match ha terminato
(oppure all'inizio della stringa nel primo match). Poiché
m/ \G( \d+\b )/gcx utilizza il flag c, se la stringa non soddisfa
l'espressione regolare, il perl non reinizializza pos() ed il match
successivo inizia alla stessa posizione per tentare un pattern differente.
|