O que eu fiz de errado aqui?
Tentar corresponder qualquer string que contenha espaços, letras minúsculas, maiúsculas ou números. Caracteres especiais também seriam legais, mas acho que isso requer o escape de certos caracteres.
TEST="THIS is a TEST title with some numbers 12345 and special char *&^%$#"
if [[ "$TEST" =~ [^a-zA-Z0-9\ ] ]]; then BLAH; fi
Obviamente, isso só testa superior, inferior, números e espaços. Mas não funciona.
* ATUALIZAÇÃO *
Eu acho que deveria ter sido mais específico. Aqui está a linha de código real real.
if [[ "$TITLE" =~ [^a-zA-Z0-9\ ] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; fi
* ATUALIZAÇÃO *
./anm.sh: line 265: syntax error in conditional expression
./anm.sh: line 265: syntax error near `&*#]'
./anm.sh: line 265: ` if [[ ! "$TITLE" =~ [a-zA-Z0-9 $%^\&*#] ]]; then RETURN="FAIL" && ERROR="ERROR: Title can only contain upper and lowercase letters, numbers, and spaces!"; return; fi'
regex
bash
if-statement
Atomiklan
fonte
fonte
re='...whatever...'; [[ $string =~ $re ]]
(sem aspas - este é um dos raros casos em que eles quebram algo que funcionaria sem eles).[[ $var =~ .* ]]
para match regex.*
(qualquer coisa). Eu acho que se você usar aspas, as próprias aspas são consideradas parte do regex ...pattern='^hello[0-9]*$'
(2.) na expressão de quadrado duplo se você precisar de correspondência de regex, NÃO indique o padrão porque a citação DESATIVA a correspondência de padrão de regex. (ou seja, a expressão[[ "$x" =~ $pattern ]]
corresponderá usando regex e a expressão[[ "$x" =~ "$pattern" ]]
desativa a correspondência de regex e é equivalente a[[ "$x" == "$pattern" ]]
).Respostas:
Há algumas coisas importantes que você deve saber sobre a
[[ ]]
construção do bash . O primeiro:A segunda coisa:
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:
# This doesn't work: 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 $%&#' # add almost whatever else you want to allow to the list 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:[][-]
)fonte
if ! [[ $x =~ $y ]]
ouif [[ ! $x =~ $y ]]
SC2076: Don't quote rhs of =~, it'll match literally rather than as a regex.
[[
e]]
" são analisadas fora do texto do programa, da mesma forma que as linhas de comando são analisadas em palavras. Ao contrário das linhas de comando, porém, as palavras não são divididas após as expansões.Caso alguém queira um exemplo usando variáveis ...
#!/bin/bash # Only continue for 'develop' or 'release/*' branches BRANCH_REGEX="^(develop$|release//*)" if [[ $BRANCH =~ $BRANCH_REGEX ]]; then echo "BRANCH '$BRANCH' matches BRANCH_REGEX '$BRANCH_REGEX'" else echo "BRANCH '$BRANCH' DOES NOT MATCH BRANCH_REGEX '$BRANCH_REGEX'" fi
fonte
Eu prefiro usar
[:punct:]
para isso. Além disso,a-zA-Z09-9
pode ser apenas[:alnum:]
:[[ $TEST =~ ^[[:alnum:][:blank:][:punct:]]+$ ]]
fonte
Ou você pode estar olhando para esta pergunta porque aconteceu de você cometer um erro de digitação bobo como eu fiz e ter o = ~ revertido para ~ =
fonte