Eu vi este exemplo:
hello=ho02123ware38384you443d34o3434ingtod38384day echo ${hello//[0-9]/}
Que segue esta syntax: ${variable//pattern/replacement}
Infelizmente, o campo pattern
não parece suportar a syntax de regex completa (se eu usar .
Ou \s
, por exemplo, ele tenta corresponder aos caracteres literais).
Como posso pesquisar / replace uma string usando a syntax de regex completa?
Use sed :
MYVAR=ho02123ware38384you443d34o3434ingtod38384day echo $MYVAR | sed -e 's/[a-zA-Z]/X/g' -e 's/[0-9]/N/g' # prints XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX
Observe que os -e
subseqüentes são processados em ordem. Além disso, o sinalizador g
da expressão corresponderá a todas as ocorrências na input.
Você também pode escolher sua ferramenta favorita usando este método, por exemplo, perl, awk, por exemplo:
echo $MYVAR | perl -pe 's/[a-zA-Z]/X/g and s/[0-9]/N/g'
Isso pode permitir que você faça mais correspondências criativas … Por exemplo, no recorte acima, a substituição numérica não seria usada, a menos que houvesse uma correspondência na primeira expressão (devido a lentidão and
avaliação). E, claro, você tem o suporte completo de idiomas do Perl para fazer o seu lance …
Isso realmente pode ser feito em puro bash:
hello=ho02123ware38384you443d34o3434ingtod38384day re='(.*)[0-9]+(.*)' while [[ $hello =~ $re ]]; do hello=${BASH_REMATCH[1]}${BASH_REMATCH[2]} done echo "$hello"
…rendimentos…
howareyoudoingtodday
Estes exemplos também funcionam no bash sem necessidade de usar o sed:
#!/bin/bash MYVAR=ho02123ware38384you443d34o3434ingtod38384day MYVAR=${MYVAR//[a-zA-Z]/X} echo ${MYVAR//[0-9]/N}
você também pode usar as expressões de colchete de class de caractere
#!/bin/bash MYVAR=ho02123ware38384you443d34o3434ingtod38384day MYVAR=${MYVAR//[[:alpha:]]/X} echo ${MYVAR//[[:digit:]]/N}
saída
XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX
O que @Lanaru queria saber no entanto, se eu entendi a pergunta corretamente, é por que as extensões “full” ou PCRE \s\S\w\W\d\D
etc não funcionam como suportado no php ruby python etc. As extensões são de expressões regulares compatíveis com Perl (PCRE) e podem não ser compatíveis com outras formas de expressões regulares baseadas em shell.
Estes não funcionam:
#!/bin/bash hello=ho02123ware38384you443d34o3434ingtod38384day echo ${hello//\d/} #!/bin/bash hello=ho02123ware38384you443d34o3434ingtod38384day echo $hello | sed 's/\d//g'
saída com todos os caracteres “d” literais removidos
ho02123ware38384you44334o3434ingto38384ay
mas o seguinte funciona como esperado
#!/bin/bash hello=ho02123ware38384you443d34o3434ingtod38384day echo $hello | perl -pe 's/\d//g'
saída
howareyoudoingtodday
Espero que esclareça um pouco mais as coisas, mas se você ainda não está confuso, por que você não experimenta isso no Mac OS X que tem o sinalizador REG_ENHANCED habilitado:
#!/bin/bash MYVAR=ho02123ware38384you443d34o3434ingtod38384day; echo $MYVAR | grep -o -E '\d'
Na maioria dos sabores do * nix, você verá apenas a seguinte saída:
d d d
nJoy!
Use [[:digit:]]
(observe os colchetes duplos) como o padrão:
$ hello=ho02123ware38384you443d34o3434ingtod38384day $ echo ${hello//[[:digit:]]/} howareyoudoingtodday
Só queria resumir as respostas (especialmente https://stackoverflow.com/a/22261334/2916086 do @ nickl-.
Se você está fazendo chamadas repetidas e está preocupado com o desempenho, este teste revela que o método BASH é ~ 15x mais rápido do que o pedido e provavelmente qualquer outro processo externo.
hello=123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X P1=$(date +%s) for i in {1..10000} do echo $hello | sed s/X//g > /dev/null done P2=$(date +%s) echo $[$P2-$P1] for i in {1..10000} do echo ${hello//X/} > /dev/null done P3=$(date +%s) echo $[$P3-$P2]