Asserzioni

L'asserzione è un test basato su un carattere, che può precedere o seguire l'attuale punto di riconoscimento, e non consuma alcun carattere. Le semplici asserzioni quali \b, \B, \A, \Z, \z, ^ e $ sono state descritte precedentemente. Asserzioni più complesse possono essere strutturate come delle sotto-regole. Se ne hanno di due tipologie: quelle che guardano avanti alla posizione attuale nella stringa oggetto del riconoscimento, e quelle che guardano dietro la posizione attuale.

Una asserzione definita come sotto-regola esegue il riconoscimento nel modo usuale, ma tale riconoscimento non sposta la posizione attuale nella stringa. Le asserzioni che "guardano avanti" cominciano per "(?=", se sono positive, per "(?!", se sono asserzioni negative. Ad esempio \w+(?=;) riconosce una parola seguita da ";", ma non include il punto e virgola nel riconoscimento, mentre foo(?!bar) identifica qualsiasi occorrenza di "foo" che non sia seguita da "bar". Attenzione che il criterio, apparentemente simile, (?!foo)bar non riconosce alcuna occorrenza di "bar" se questa è preceduta da qualsiasi testo che non sia "foo"; infatti l'espressione riconosce qualsiasi occorrenza di "bar", poiché l'asserzione (?!foo) è sempre true quando i tre caratteri successivi sono "bar". Pertanto è necessario una asserzione che "guarda" all'indietro per ottenere effetto desiderato.

Le asserzioni che "guardano" indietro positive iniziano con "(?<=", e con "(?<!" le negative. Ad esempio: (?<!foo)bar riconosce una occorrenza di "bar" che non sia preceduta da "foo". Le asserzioni che "guardano" indietro hanno una limitazione: tutte le stringhe che riconoscono devono avere lunghezza fissa. Mentre, se si hanno casi alternativi, la limitazione della lunghezza fissa non sussiste. Quindi (?<=bullock|donkey) è una asserzione permessa, ma (?<!dogs?|cats?) genera un errore durante la fase di compilazione. Rami alternativi con lunghezze di stringa differenti sono permessi solo al primo livello dell'asserzione. Questa è da considerarsi una estensione rispetto a Perl 5.005, che richiede a tutte le alternative possibili la medesima lunghezza di stringa. Quindi una asserzione tipo (?<=ab(c|de)) non è permessa, poiché il suo singolo ramo di primo livello può identificare testi di due lunghezze differenti, ma è accettabile se riscritta usando due alternative di primo livello: (?<=abc|abde) L'implementazione di questo tipo di asserzioni consiste, per ciascuna alternativa, di uno spostamento all'indietro temporaneo per la lunghezza fissa necessaria, e ad un tentativo di riconoscimento del testo. Se non ci sono sufficienti caratteri precedenti alla posizione attuale, l'asserzione è destinata a fallire. L'uso accoppiato delle asserzioni che "guardano" indietro con sotto-regole a riconoscimento singolo può essere utile per identificare la fine dei testi; un esempio è illustrato al termine della sezione sulle sotto-regole a riconoscimento singolo.

Diverse asserzioni (di qualsiasi tipologia) possono essere utilizzate in modo consecutivo. Ad esempio: (?<=\d{3})(?<!999)foo riconosce "foo" preceduto da tre cifre che non siano "999". Occorre rilevare che ciascuna asserzione viene applicata singolarmente sul medesimo punto nella stringa oggetto di riconoscimento. Nell'esempio precedente per prima cosa si verifica che i tre caratteri precedenti siano cifre, quindi che non siamo "999". Questo esempio non identifica il testo se "foo" è preceduto da sei caratteri di cui i primi tre siano cifre e i secondi tre non siano "999". In pratica il testo "123abcfoo" non viene riconosciuto. Un criterio per riconoscere tale stringa può essere: (?<=\d{3}...)(?<!999)foo

In questo caso la prima asserzione controlla i primi sei caratteri verificando che i primi tre siano cifre, mentre la seconda asserzione verifica che i secondi tre caratteri non siano "999".

Le asserzioni possono essere annidate in qualsiasi combinazione. Il seguente esempio (?<=(?<!foo)bar)baz identifica il testo "baz" se è preceduto da "bar" il quale non deve essere preceduto da "foo", mentre (?<=\d{3}...(?<!999))foo è un'altro criterio che riconosce "foo" preceduto da tre cifre e da tre caratteri che non siano "999".

Le asserzioni definite come sotto-regole non catturano parte del testo e non possono essere ripetute (non avrebbe senso ripetere il medesimo riconoscimento sul medesimo testo). Se una di queste asserzioni contiene una sotto-regola di cattura questa viene conteggiata ai fini della numerazione delle regole di cattura. Tuttavia il testo viene effettivamente catturato solo nelle asserzioni positive, dato che non avrebbe senso farlo in quelle negative.

Le asserzioni possono essere composte fino ad un massimo di 200 sotto-regole.

add a note add a note

User Contributed Notes 1 note

up
-4
daevid at daevid dot com
11 years ago
removes // comments but NOT the stuff after http://

$sBlob = preg_replace("@\s*(?<!:)//.*?$@m",'',$sBlob);

Although, as Sean Greenslade pointed out, it will fail in this EDGE case since the comments are within quotes, but who does that anyways?

"Lol slashes // are // fun";
To Top