Successivo: , Precedente: , Su: Espressioni regolari   [Contenuti][Indice]


3.6 Usare regexp dinamiche

L’espressione a destra di un operatore ‘~’ o ‘!~’ non deve necessariamente essere una costante regexp (cioè, una stringa di caratteri tra barre). Può essere una qualsiasi espressione. L’espressione è valutata e convertita in una stringa se necessario; il contenuto della stringa è poi usato come una regexp. Una regexp calcolata in questo modo è detta una regexp dinamica o una regexp calcolata:

BEGIN { regexp_numerica = "[[:digit:]]+" }
$0 ~ regexp_numerica    { print }

Questo script imposta regexp_numerica come una regexp che descrive una o più cifre, e poi controlla se un record in input corrisponde a questa regexp.

NOTA: Usando gli operatori ‘~’ e ‘!~’, si tenga presente che c’è una differenza tra una costante regexp racchiusa tra barre e una costante stringa racchiusa tra doppi apici. Se si intende utilizzare una costante stringa, occorre comprendere che la stringa è, in sostanza, scandita due volte: la prima volta quando awk legge il programma, e la seconda volta quando va a confrontare la stringa a sinistra dell’operatore con il modello che sta alla sua destra. Questo vale per ogni espressione (come la regexp_numerica, vista nel precedente esempio), non solo per le costanti stringa.

Che differenza fa la doppia scansione di una stringa? La risposta ha a che vedere con le sequenze di protezione e particolarmente con le barre inverse. Per inserire una barra inversa in un’espressione regolare all’interno di una stringa, occorre inserire due barre inverse.

Per esempio, /\*/ è una costante regexp per designare un ‘*’ letterale. È richiesta una sola barra inversa. Per fare lo stesso con una stringa, occorre immettere "\\*". La prima barra inversa protegge la seconda in modo che la stringa in realtà contenga i due caratteri ‘\’ e ‘*’.

Dato che si possono usare sia costanti regexp che costanti stringa per descrivere espressioni regolari, qual è da preferire? La risposta è “costanti regexp”, per molti motivi:

Usare \n in espressioni tra parentesi quadre in regexp dinamiche

Alcune delle prime versioni di awk non consentono di usare il carattere di ritorno a capo all’interno di un’espressione tra parentesi quadre in regexp dinamiche:

$ awk '$0 ~ "[ \t\n]"'
error→ awk: newline in character class [
error→ ]...
error→  source line number 1
error→  context is
error→        $0 ~ "[ >>>  \t\n]" <<<

Ma un ritorno a capo in una costante regexp non dà alcun problema:

$ awk '$0 ~ /[ \t\n]/'
ecco una riga di esempio
-| ecco una riga di esempio
Ctrl-d

gawk non ha questo problema, e non dovrebbe accadere spesso in pratica, ma val la pena di notarlo a futura memoria.


Successivo: , Precedente: , Su: Espressioni regolari   [Contenuti][Indice]