Resumo:
Intervalo: você precisa alterar o LANG em um subnível: (LANG=C; echo "${a//[^a-zA-Z]}")
Lista: caracteres explícitos: r1=$(printf '%s' {a..z} {A..Z} {0-9})
Construa regex em partes: r2="[$r1]"; r3="[$r1-]"; reg="^$r2($r3{0,61}$r2)?$"
Use a regex final como: if [[ ! $SUBDOMAIN =~ $reg ]]; then
intervalos
A correspondência do intervalo a-z ou A-Z oculta várias surpresas.
Uma regex simples (ou glob) como [a-z]
corresponderá a muitos outros caracteres:
$ a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
$ echo "${a//[^a-z]}"
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY
Observe que apenas o Z
foi removido. A localidade pode mudar isso:
$ LANG=C
$ echo "${a//[^a-z]}"
abcdefghijklmnopqrstuvwxyz
É ainda pior se o intervalo [[:alnum:]]
for usado:
$ LANG=en_US.utf8
$ a='aáàäåbcdeéèëfAÁÀÄBßCRS§TUVWXYZ'
$ echo "${a//[^a-z]} ${a//[[:alnum:]]}"
aáàäåbcdeéèëfAÁÀÄBßCRSTUVWXY aáàäåbcdeéèëfAÁÀÄBßCRSTUVWXYZ
O primeiro intervalo removido §Z
, alnum
removeu apenas o §
.
Com LANG = C, fica melhor:
$ LANG=C
$ a='aáàäåbcdeéèëfAÁÀÄBßCRS§TUVWXYZ'
$ echo "${a//[^a-z]} ${a//[^[:alnum:]]}"
abcdef áàäåéèëÁÀÄߧ
Um intervalo para incluir o Z
pode funcionar melhor.
$ LANG=en_US.utf8
$ a='ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_'abcdefghijklmnopqrstuvwxyz'
$ echo "${a//[^a-Z]}"
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
Mas ainda incluirá muitos outros caracteres UNICODE.
$ LANG=en_US.utf8
$ a='AÁÀÄBßCRSTUVWXYZ[]^_'aáàäåbcdeéèëf-ěžíňř'
$ echo "${a//[^a-Z]}"
AÁÀÄBßCRSTUVWXYZaáàäåbcdeéèëfěíňř
E usando a configuração da linguagem C, basta alterar o problema para:
$ LANG=C
$ a='AÁÀÄBßCRSTUVWXYZ[]^_'aáàäåbcdeéèëfxyz-ěžíňř'
$ echo "${a//[^A-z]} ${a//[^[:alnum:]]}"
ABCRSTUVWXYZ[]^_'abcdefxyz ABCRSTUVWXYZabcdefxyz
Subshell
Para usar a opção LANG=C
, é comum precisar de um sub-shell para evitar alterar o valor de LANG no shell em execução:
$ (LANG=C; echo "${a//[^a-zA-Z]}")
ABCRSTUVWXYZabcdefxyz
Lista
Uma lista explícita de caracteres evitará tanto a questão do agrupamento quanto a necessidade de alterar a variável LANG (expansões de chaves usam apenas o local padrão C):
$ r1=$(printf '%s' {a..z} {A..Z})
$ echo "$r1"
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
$ a='AÁÀÄBßCRSTUVWXYZ[]^_'aáàäåbcdeéèëfxyz-ěžíňř'
$ echo "${a//[^"$r1"]}"
ABCRSTUVWXYZabcdefxyz
Para A-Z, a-z e 0-9, use:
r1=$(printf '%s' {A..Z} {a..z} {0..9})
Em seguida, crie os dois tipos de valores de expressão regular necessários:
r2="[$r1]"
r3="[$r1-]"
E o regex completo será:
reg="^$r2($r3{0,61}$r2)?$"
use como (é melhor que o regex esteja dentro de uma variável):
if [[ ! $SUBDOMAIN =~ $reg ]]; then