#!/bin/bash
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
echo "INT is an integer."
else
echo "INT is not an integer." >&2
exit 1
fi
Cosa fa il protagonista ~
nell'espressione regolare iniziale?
#!/bin/bash
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
echo "INT is an integer."
else
echo "INT is not an integer." >&2
exit 1
fi
Cosa fa il protagonista ~
nell'espressione regolare iniziale?
Risposte:
In ~
realtà fa parte dell'operatore =~
che esegue una corrispondenza di espressione regolare della stringa alla sua sinistra con l'espressione regolare estesa alla sua destra.
[[ "string" =~ pattern ]]
Si noti che la stringa deve essere quotata e che l'espressione regolare non deve essere quotata.
Un operatore simile viene utilizzato nel linguaggio di programmazione Perl.
Le espressioni regolari comprese bash
sono le stesse di quelle che GNU grep
comprende con la -E
bandiera, ovvero l'insieme esteso di espressioni regolari.
Un po 'fuori tema, ma buono a sapersi:
Quando si esegue la corrispondenza con un'espressione regolare contenente gruppi di acquisizione, la parte della stringa acquisita da ciascun gruppo è disponibile BASH_REMATCH
nell'array. Lo zeroth / primo ingresso in questo array corrisponde &
al pattern di sostituzione di sed
comando 's sostituzione (o $&
in Perl), che è il bit della stringa che corrisponde al modello, mentre le voci di indice 1 e poi corrisponde \1
, \2
ecc in un sed
modello di sostituzione (o $1
, $2
ecc. in Perl), ovvero i bit corrispondenti a ciascuna parentesi.
Esempio:
string=$( date +%T )
if [[ "$string" =~ ^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$ ]]; then
printf 'Got %s, %s and %s\n' \
"${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
fi
Questo può produrre
Got 09, 19 and 14
se l'ora corrente risulta essere 09:19:14.
Il REMATCH
bit del BASH_REMATCH
nome dell'array deriva da "Corrispondenza espressioni regolari", ovvero "Corrispondenza RE".
In bash
shell non simili a Bourne, si può anche usare expr
per una corrispondenza limitata delle espressioni regolari (usando solo espressioni regolari di base).
Un piccolo esempio:
$ string="hello 123 world"
$ expr "$string" : ".*[^0-9]\([0-9][0-9]*\)"
123
grep -E
comprende solo sui sistemi GNU e solo quando si utilizza una variabile non quotata come modello [[ $var = $pattern ]]
(vedere [[ 'a b' =~ a\sb ]]
vs p='a\sb'; [[ 'a b' =~ $p ]]
). Attenzione anche che la quotazione della shell influisce sul significato degli operatori RE e che alcuni caratteri devono essere citati per il tokenizzazione della shell che potrebbe influenzare l'elaborazione RE. [[ '\' =~ [\/] ]]
restituisce false. ksh93
ha problemi anche peggiori. Vedi zsh
(o bash 3.1) per un approccio più sano in cui shell e quotazione RE sono chiaramente separate. Il [
built-in zsh
e yash
anche un =~
operatore.
off-topic
! +1 (
[[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]
. O che anche un citato *
corrisponda? [[ "This is a fine mess." =~ "T.........fin*es*" ]]
.
[[ a =~ .* ]]
o [[ a =~ '.*' ]]
o [[ a =~ \.\* ]]
, la stessa .*
RE viene passata =~
all'operatore. OTH, in bash
, [[ '\' =~ [)] ]]
restituisce un errore, lo sapresti senza provare se [[ '\' =~ [\)] ]]
corrisponde? Che ne dici [[ '\' =~ [\/] ]]
(lo fa in ksh93). Che ne dici c='a-z'; [[ a =~ ["$c"] ]]
(confronta con l' =
operatore)? Vedi anche: [[ '\' =~ [^]"."] ]]
che restituisce falso ... Nota che si può fare shopt -s compat31
in bash
per ottenere il zsh
comportamento.
zsh
/ bash -o compat31
'S comportamento per [[ a =~ '.*' ]]
è anche coerente con [ a '=~' '.*' ]
(per [
implementazioni che di supporto =~
) o expr a : '.*'
. OTOH, non è coerente con [[ a = '*' ]]
vs [[ a = * ]]
(ma poi i globs fanno parte del linguaggio shell, mentre le RE non lo sono).
Dovresti leggere le pagine man di bash, sotto la [[ expression ]]
sezione.
An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).
Per farla breve, =~
è un operatore, proprio come ==
e !=
. Non ha nulla a che fare con l'attuale regex nella stringa alla sua destra.
=~
nella vita reale ...?
man [[ expresssion ]]
e man [[
non restituire nulla. help [[
restituisce informazioni utili — da [[
un comando bash interno — ma non dice se =~
usa la sintassi regex di base o estesa. ⋯ Il testo che hai citato proviene dalla pagina man di bash . Mi rendo conto che hai detto "leggi le pagine man di bash", ma all'inizio pensavo volessi leggere le pagine man di bash. Ad ogni modo, man bash
restituisce un file enorme, che è lungo 4139 righe (72 pagine). Può essere cercato premendo /▒▒▒
, che richiede una regex, il cui sapore - come =~
- non è specificato.