Eu já vi este exemplo:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
O que segue esta sintaxe: ${variable//pattern/replacement}
Infelizmente, o pattern
campo parece não suportar sintaxe de regex completa (se eu usar .
ou \s
, por exemplo, tentar corresponder aos caracteres literais).
Como posso procurar / substituir uma string usando a sintaxe regex completa?
\s
não faz parte da sintaxe de expressão regular definida pelo POSIX (nem BRE nem ERE); é uma extensão PCRE e, principalmente, não está disponível no shell.[[:space:]]
é o equivalente mais universal.\s
podem ser substituídos por[[:space:]]
, a propósito,.
por?
, e extensões extglob para a linguagem de padrão de linha de base da linha de base podem ser usadas para itens como subgrupos opcionais, grupos repetidos e similares.Respostas:
Use sed :
Observe que os subsequentes
-e
são processados em ordem. Além disso, og
sinalizador para a expressão corresponderá a todas as ocorrências na entrada.Você também pode escolher sua ferramenta favorita usando este método, por exemplo, perl, awk, por exemplo:
Isso pode permitir que você faça correspondências mais criativas ... Por exemplo, no snip acima, a substituição numérica não seria usada a menos que houvesse uma correspondência na primeira expressão (devido a uma
and
avaliação lenta ). E, claro, você tem o suporte completo ao Perl para fazer sua licitação ...fonte
sed
outras ferramentas externas é caro devido ao tempo de inicialização do processo. Eu procurei especialmente pela solução all-bash, porque achei que o uso de substituições do bash era mais do que 3x mais rápido do que chamarsed
cada item do meu loop.Na verdade, isso pode ser feito no puro bash:
...rendimentos...
fonte
=~
É a chave. Mas um pouco desajeitado, dada a reatribuição no loop. A solução @jheddings 2 anos antes é outra boa opção - chamar sed ou perl).sed
ouperl
é sensível, se estiver usando cada chamada para processar mais de uma única linha de entrada. Invocar essa ferramenta no interior de um loop, em vez de usar um loop para processar seu fluxo de saída, é imprudente.$match
vez de$BASH_REMATCH
. (Você pode fazê-lo comportar-se como festa comsetopt bash_rematch
.)Estes exemplos também funcionam no bash, sem a necessidade de usar o sed:
você também pode usar as expressões de colchete da classe de caracteres
resultado
O que o @Lanaru queria saber, no entanto, se entendi a pergunta corretamente, é por que as extensões "completa" ou PCRE
\s\S\w\W\d\D
etc. não funcionam como suportadas no php ruby python etc. Essas extensões são de expressões regulares compatíveis com Perl (PCRE) e pode não ser compatível com outras formas de expressões regulares baseadas em shell.Estes não funcionam:
saída com todos os caracteres literais "d" removidos
mas o seguinte funciona como esperado
resultado
Espero que esclareça um pouco mais as coisas, mas se você ainda não está confuso, por que não tenta isso no Mac OS X, com o sinalizador REG_ENHANCED ativado:
Na maioria dos tipos de * nix, você verá apenas a seguinte saída:
nJoy!
fonte
${foo//$bar/$baz}
é a sintaxe POSIX.2 BRE ou ERE - é a correspondência de padrões no estilo fnmatch ().${hello//[[:digit:]]/}
trabalho, se quiséssemos filtrar apenas os dígitos precedidos pela letrao
,${hello//o[[:digit:]]*}
teria um comportamento completamente diferente do esperado (já que nos padrões fnmatch,*
corresponde a todos os caracteres, em vez de modificar o item imediatamente anterior a ser 0 ou mais).[0-9]
ou[[:digit:]]
Se você estiver fazendo chamadas repetidas e se preocupa com o desempenho, este teste revela que o método BASH é aproximadamente 15x mais rápido do que fazer bifurcação para sed e provavelmente qualquer outro processo externo.
fonte
Use
[[:digit:]]
(observe os colchetes duplos) como padrão:Só queria resumir as respostas (especialmente os https://stackoverflow.com/a/22261334/2916086 da @ nickl- ).
fonte