bash espressione condizionale e backslash escaping
Ho davvero difficoltà a capire questo comportamento:
stackExchange@test:~$ if [[ "two words" =~ \bwords ]]; then echo hi; fi; #(I'd expect this one worked) stackExchange@test:~$ if [[ "two words" =~ \\bwords ]]; then echo hi; fi; #(or at least this one...)
stackExchange@test:~$ if [[ "two words" =~ \\\bwords ]]; then echo hi; fi; stackExchange@test:~$ if [[ "two words" =~ \\\\bwords ]]; then echo hi; fi;
stackExchange@test:~$ put_in_a_variable=\\bwords stackExchange@test:~$ if [[ "two words" =~ $put_in_a_variable ]]; then echo hi; fi; hi stackExchange@test:~$
Capisco che la mia variabile contiene \bworde questo è stato espanso nella sezione pattern dell'espressione condizionale, ma non riesco davvero a capire perché sembra impossibile ottenere lo stesso comportamento usando l'escape della shell inline.
Non voglio fare qualcosa di simile if [[ "two words" =~ $(echo \\bwords) ]]; then echo hi; fi;; troppo strano...
Grazie,
Francesco
Risposte
L'effetto di una barra rovesciata nella parte dell'espressione regolare di [[ str =~ rex ]]è di citare il seguente carattere (esattamente come metterlo tra virgolette singole), che indicherebbe a bash di fare una corrispondenza letterale per esso (1). Poiché bnon è speciale, \bsi trasformerà in giusto b, ma '\', "\\"o \\si trasformerà in \\per abbinare una barra rovesciata letterale:
[[ abwords =~ \bwords ]] && echo "<$BASH_REMATCH>" <bwords> [[ 'a\bwords' =~ \\bwords ]] && echo "<$BASH_REMATCH>"
<\bwords>
# conversely, '|' is just like \|
[[ 'a|words' =~ a'|'words ]] && echo "<$BASH_REMATCH>"
<a|words>
La tua idea di inserire la regex in una variabile va bene. Un'alternativa sarebbe usare una funzione wrapper:
rematch() [[ $1 =~ $2 ]] if rematch 'two words' '\bwords\b'; then echo "<$BASH_REMATCH>"
fi
<words>
(1): come documentato nel suo manuale :
Qualsiasi parte del modello può essere citata per forzare la corrispondenza tra la parte citata come stringa
Si noti che nella shell, i caratteri citati sono effettivamente contrassegnati in modo speciale , quindi qualsiasi elaborazione successiva da parte del parser potrebbe basare le decisioni sul fatto che una parte di una stringa sia stata quotata o meno.