Há algumas coisas importantes que você deve saber sobre a [[ ]]
construção do bash . O primeiro:
A divisão de palavras e a expansão do nome do caminho não são executadas nas palavras entre [[
e ]]
; Expansão til, expansão de parâmetro e variável, expansão aritmética, substituição de comando, substituição de processo e remoção de cotação são executadas.
A segunda coisa:
Um operador binário adicional, '= ~', está disponível, ... a string à direita do operador é considerada uma expressão regular estendida e correspondida de acordo ... Qualquer parte do padrão pode ser citada para forçar a correspondência como uma string .
Conseqüentemente, $v
em qualquer lado do =~
será expandido para o valor daquela variável, mas o resultado não será dividido por palavras ou expandido pelo nome do caminho. Em outras palavras, é perfeitamente seguro deixar as expansões variáveis sem aspas no lado esquerdo, mas você precisa saber que as expansões variáveis acontecerão no lado direito.
Então, se você escrever: [[ $x =~ [$0-9a-zA-Z] ]]
o $0
interior do regex à direita será expandido antes do regex é interpretado, o que provavelmente fará com que o regex para não compilar (a menos que a expansão das $0
extremidades com um símbolo de dígitos ou pontuação cujo valor ASCII é menor do que um dígito). Se você citar o lado direito da mesma maneira [[ $x =~ "[$0-9a-zA-Z]" ]]
, o lado direito será tratado como uma string comum, não uma regex (e $0
ainda será expandido). O que você realmente quer neste caso é[[ $x =~ [\$0-9a-zA-Z] ]]
Da mesma forma, a expressão entre [[
e ]]
é dividida em palavras antes que a regex seja interpretada. Portanto, os espaços no regex precisam ter escape ou entre aspas. Se você queria para combinar letras, números ou espaços que você poderia usar: [[ $x =~ [0-9a-zA-Z\ ] ]]
. Outros caracteres também precisam de escape, como #
, o que iniciaria um comentário se não fosse citada. Claro, você pode colocar o padrão em uma variável:
pat="[0-9a-zA-Z ]"
if [[ $x =~ $pat ]]; then ...
Para regexes que contêm muitos caracteres que precisariam ser escapados ou citados para passar pelo lexer do bash, muitas pessoas preferem esse estilo. Mas cuidado: neste caso, você não pode citar a expansão da variável:
if [[ $x =~ "$pat" ]]; then ...
Finalmente, acho que o que você está tentando fazer é verificar se a variável contém apenas caracteres válidos. A maneira mais fácil de fazer essa verificação é certificar-se de que não contém um caractere inválido. Em outras palavras, uma expressão como esta:
valid='0-9a-zA-Z $%&#'
if [[ ! $x =~ [^$valid] ]]; then ...
!
nega o teste, transformando-o em um operador "não corresponde", e uma [^...]
classe de caractere regex significa "qualquer caractere diferente de ...
".
A combinação de expansão de parâmetro e operadores regex pode tornar a sintaxe da expressão regular do bash "quase legível", mas ainda existem algumas pegadinhas. (Não há sempre?) Uma é que você não poderia colocar]
em $valid
, mesmo que $valid
foram citados, exceto no início. (Essa é uma regra Posix regex: se você quiser incluir ]
em uma classe de caractere, ela precisa ir no início. -
Pode ir no início ou no final, então se você precisa de ambos ]
e -
, você precisa começar ]
e terminar com -
, levando à regex "Eu sei o que estou fazendo" emoticon: [][-]
)