Diferentes ferramentas e suas versões suportam diferentes variantes de expressões regulares. A documentação de cada um lhe dirá o que eles suportam.
Existem padrões para que você possa confiar em um conjunto mínimo de recursos disponíveis em todos os aplicativos em conformidade.
Por exemplo, todas as implementações modernas sed
e grep
implementam expressões regulares básicas, conforme especificado pelo POSIX (pelo menos uma versão ou outra do padrão, mas esse padrão não evoluiu muito nesse sentido nas últimas décadas).
No POSIX BRE e ERE, você tem a [:alnum:]
classe de caracteres. Isso corresponde a letras e dígitos no seu código de idioma (observe que geralmente inclui muito mais do que a-zA-Z0-9
, a menos que o código de idioma seja C).
Tão:
grep -x '[[:alnum:]_]\{1,\}'
corresponde a um ou mais alnums ou _.
[\w]
é requerido pelo POSIX para corresponder à barra invertida ou w
. Portanto, você não encontrará uma grep
ou sed
implementação onde esteja disponível (a menos que seja através de opções fora do padrão).
O comportamento \w
sozinho não é especificado pelo POSIX, portanto, as implementações podem fazer o que desejam. O GNU grep
acrescentou isso há muito tempo.
O GNU grep
costumava ter seu próprio mecanismo de expressão regular, mas agora usa o mecanismo do GNU libc (embora ele incorpore sua própria cópia).
Ele serve para combinar alnums e sublinhado em seu local. No entanto, atualmente existe um erro, pois corresponde apenas a caracteres de byte único (por exemplo, não é em um código de idioma UTF-8, mesmo que isso seja claramente uma letra e mesmo que corresponda a em todas as localidades em que é um único personagem).
Também existe um \w
operador regexp no perl regexp e no PCRE. PCRE / perl não são expressões regulares POSIX, são apenas outra coisa.
Agora, com a maneira como o GNU grep -P
usa o PCRE, ele tem o mesmo problema que sem -P
. No entanto, pode ser trabalhado por aí usando (*UCP)
(embora isso também tenha efeitos colaterais em locais não UTF8).
O GNU sed
também usa os regexs do GNU libc para seus próprios regexps. Ele o usa de tal maneira que não possui o mesmo bug que o GNU grep
.
O GNU sed
não suporta PCREs. Há alguma evidência no código de que ele foi tentado antes, mas parece que não está mais na agenda.
Se você quiser expressões regulares do Perl, use-as perl
.
Caso contrário, eu diria que, em vez de tentar confiar em um recurso não-padrão falso de sua implementação específica de sed
/ grep
, seria melhor seguir o padrão e o uso [_[:alnum:]]
.
[_[:alnum:]]
é uma boa solução alternativa que me permite estendê-la exatamente como[\w/]
([_[:alnum:]/]
nesse caso).grep
.Você está correto -
\w
faz parte das expressões regulares compatíveis com PCRE - perl. Porém, não faz parte da regex 'padrão'. http://www.regular-expressions.info/posix.htmlAlgumas versões
sed
podem suportá-lo, mas eu sugiro que a maneira mais fácil é usar apenasperl
nosed
modo, especificando o-p
sinalizador. (Junto com o-e
). (Mais detalhes emperlrun
)Mas você não precisa
[]
contornar esse exemplo - isso é para grupos de coisas válidas.Ou no Windows:
Veja
perlre
para mais informações sobre o PCRE.Você pode obter o perl aqui: http://www.activestate.com/activeperl/downloads
fonte
\w
e[\w]
na minha pergunta. Vou atualizá-lo com saídas de cada comando para deixar claro qual deles está funcionando e qual não está. Em particular,sed
entende\w
, mas não[\w]
. Além disso, preciso[\w]
trabalhar porque quero usar,[\w/]
por exemplo.perl
pode fazê-lo :).\w
estava no GNU grep (nos anos 80) antes de estar em perl e no GNU emacs provavelmente antes mesmo disso.Eu suspeito que
grep
esed
esteja decidindo diferentemente quando aplicar o[]
e quando expandir o\w
. Em perl regex\w
significa qualquer caractere de palavra e[]
define um grupo para aplicar qualquer um dos caracteres como uma correspondência. Se você "expandir" o\w
anterior[]
, será uma classe de caracteres de todos os caracteres da palavra. Se, em vez disso,[]
primeiro você terá uma classe de caracteres com dois caracteres\
e,w
portanto, corresponderá a qualquer padrão que contenha um ou mais desses dois caracteres.Parece que
sed
é vê-[]
lo e tratá-lo como contendo os caracteres exatos a serem correspondidos em vez de honrar a sequência especial\w
comoperl
e ogrep
faz. É claro que[]
são completamente desnecessários neste exemplo, mas talvez se possa imaginar casos em que isso seria importante, mas você poderia fazê-lo funcionar com parênteses e ors.fonte
\
é um código de escape e você o usaria para escapar de delimitadores. Inerentemente, isso significa que deve ter uma precedência mais alta do que qualquer outra coisa. Acho mais provável que ele não está implementada porque\w
não é parte da especificação expressão regularecho whe\\ere | sed -r 's/[\w]+/gone/g
dá-megonehegoneere
como se está combinando cada um dos` and
w` e fazer a substituição