#!/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
O que o líder ~
faz na expressão regular inicial?
#!/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
O que o líder ~
faz na expressão regular inicial?
Respostas:
Na ~
verdade, é parte do operador =~
que executa uma correspondência de expressão regular da string à sua esquerda e a expressão regular estendida à sua direita.
[[ "string" =~ pattern ]]
Observe que a string deve ser citada e que a expressão regular não deve ser citada.
Um operador semelhante é usado na linguagem de programação Perl.
As expressões regulares entendidas por bash
são as mesmas que o GNU grep
entende com a -E
flag, ou seja, o conjunto estendido de expressões regulares.
Um pouco fora de tópico, mas é bom saber:
Ao fazer a correspondência com uma expressão regular que contém grupos de captura, a parte da sequência capturada por cada grupo está disponível na BASH_REMATCH
matriz. O zeroth / primeira entrada em Isto corresponde matriz para &
no padrão de substituição sed
de comando de substituição (ou $&
em Perl), que é o bit da cadeia que corresponde ao padrão, enquanto as entradas no índice 1 e seguintes corresponde a \1
, \2
, etc. . em um sed
padrão de substituição (ou $1
, $2
etc, em Perl), isto é, os bits correspondentes por cada parêntese.
Exemplo:
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
Isso pode gerar
Got 09, 19 and 14
se a hora atual for 09:19:14.
O REMATCH
bit do BASH_REMATCH
nome do array vem de "Correspondência de expressão regular", ou seja, "RE-Match".
Em bash
shells não semelhantes a Bourne, pode-se também usar expr
para correspondência limitada de expressões regulares (usando apenas expressões regulares básicas).
Um pequeno exemplo:
$ string="hello 123 world"
$ expr "$string" : ".*[^0-9]\([0-9][0-9]*\)"
123
grep -E
entende apenas nos sistemas GNU e somente ao usar uma variável não citada como padrão [[ $var = $pattern ]]
(consulte [[ 'a b' =~ a\sb ]]
vs p='a\sb'; [[ 'a b' =~ $p ]]
). Observe também que a citação do shell afeta o significado dos operadores de ER e que alguns caracteres precisam ser citados para a tokenização do shell que pode afetar o processamento do RE. [[ '\' =~ [\/] ]]
retorna falso. ksh93
tem problemas ainda piores. Veja zsh
(ou bash 3.1) para uma abordagem mais saudável, onde as cotações de shell e RE são claramente separadas. O [
builtin de zsh
e yash
também tem um =~
operador.
off-topic
! 1 (
[[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]
. Ou que um citado *
também corresponde? [[ "This is a fine mess." =~ "T.........fin*es*" ]]
.
[[ a =~ .* ]]
ou [[ a =~ '.*' ]]
ou [[ a =~ \.\* ]]
, o mesmo .*
ER é passado para o =~
operador. OTH, em bash
, [[ '\' =~ [)] ]]
retorna um erro, você saberia sem tentar se [[ '\' =~ [\)] ]]
corresponde? Que tal [[ '\' =~ [\/] ]]
(acontece no ksh93). Que tal c='a-z'; [[ a =~ ["$c"] ]]
(comparar com o =
operador)? Veja também: [[ '\' =~ [^]"."] ]]
que retorna falso ... Note que você pode fazer shopt -s compat31
em bash
para obter o zsh
comportamento.
zsh
/ bash -o compat31
'S comportamento para [[ a =~ '.*' ]]
também é consistente com [ a '=~' '.*' ]
(por [
implementações que suporte =~
) ou expr a : '.*'
. OTOH, não é consistente com [[ a = '*' ]]
vs [[ a = * ]]
(mas, os globs fazem parte da linguagem shell, enquanto os REs não).
Você deve ler as páginas do manual do bash, na [[ expression ]]
seção
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)).
Para encurtar a história, =~
é um operador, assim como ==
e !=
. Não tem nada a ver com a regex real na string à sua direita.
=~
na vida real ...?
man [[ expresssion ]]
e man [[
não devolva nada. help [[
retorna informações úteis - desde [[
um comando bash interno - mas não diz se =~
usa a sintaxe regex básica ou estendida. Text O texto que você citou é da página de manual do bash . Sei que você disse "leia as páginas de manual do bash", mas, a princípio, pensei que você pretendia ler as páginas de manual no bash. De qualquer forma, man bash
retorna um arquivo enorme, com 4139 linhas (72 páginas). Pode ser pesquisado pressionando /▒▒▒
, o que leva a uma expressão regular, cujo sabor - como =~
- não é especificado.