... | perl -pe "s/([^$filespec]*)($filespec)/ ...
Portanto, tenho uma função em que a construção acima funciona bem se $filespec
for a maioria das coisas. No entanto , se houver um traço no nome do arquivo, recebo uma Invalid [] range
mensagem.
Como posso garantir que a variável $filespec
se expanda para um nome de arquivo protegido desse tipo de erro de análise?
Suposição chave --
$filespec
é apenas um conjunto de caracteres que você deseja corresponder. Não é uma expressão regular.Vamos simular o problema com algum código
Correr que dá
O problema é acionado quando
$filespec
é expandido em sua expressão regular param/[^z-a]/
. Neste caso,z-a
é um intervalo de caracteres inválido.Para consertar você precisa escapar (pelo menos) do
-
in$filespec
. O usoquotemeta
deve fazer com que o problema desapareça, assimsaída é
Incluir isso em uma simulação de seu comando de pipeline. Primeiro, a versão do comando com falha
correr dá
e aqui está a versão corrigida
Um traço em uma expressão de colchetes é tratado como um intervalo, a menos que seja escapado com uma barra invertida 1 ou seja o primeiro ou o último caractere na expressão (ou, se a expressão for negada com
^
o primeiro caractere após^
ou o último caractere).por exemplo
[a-z]
corresponde a todos os caracteres minúsculos dea
az
(mas veja a nota 2)[a\-z]
,[-az]
, e[az-]
todos correspondem a apenas 3 caracteres:-
,a
, ez
.E, como @pmqs aponta em sua resposta,
[z-a]
é um intervalo inválido e gerará um erro.Se sua expressão regular contiver uma expressão de colchetes com um ou mais traços, você precisará modificá-la para que funcione conforme o esperado. Como na maioria das coisas, cabe a você entender o software e os recursos de linguagem que está usando bem o suficiente para fazê-los fazer o que você deseja/espera.
Consulte
man perlre
para obter detalhes sobre expressões regulares perl, incluindo recursos de conveniência e outras "pegadinhas" das quais você precisa estar ciente. Há muito nessa página de manual, você não vai dominar tudo de uma vez. Consulte-o novamente quando precisar, pois você aprenderá mais sobre como ele funciona nos próximos anos. Consulte tambémman perlrequick
para obter uma referência rápida eman perlretut
um tutorial. Eman perlrecharclass
para saber mais sobre classes de caracteres e expressões de colchetes em perl. Eman perlrebackslash
para saber mais sobre barras invertidas e sequências de escape em perl.(Se sua distribuição linux ou unix não tiver documentação perl disponível como
man
páginas, useperldoc
como comando para executar em vez deman
, por exemploperldoc perlre
).Dado que o perl tem cinco man pages principais, totalizando cerca de 54.000 palavras em prosa e exemplos dedicados apenas a expressões regulares (e mais duas que você provavelmente nunca precisará:
perlreguts
descrevendo como o mecanismo perl regex funciona eperlreapi
descrevendo a interface do plug-in do perlre), você pode estar começando a adivinhar que é um tópico complexo - e você estaria certo sobre isso.Notas:
1 nem todos os mecanismos regex suportam caracteres de escape dentro de uma expressão de colchetes. Perl faz, a maioria não - por exemplo, BRE do GNU grep (padrão, ou
-G
) e ERE (-E
) não, mas-P
regexes compatíveis com perl ( ) do GNU grep sim.2
[[:alpha:]]
,[[:upper:]]
ou[[:lower:]]
geralmente são melhores para combinar caracteres alfabéticos, pois podem funcionar com texto unicode e também com ASCII simples. Assim como[[:alnum:]]
para caracteres alfanuméricos.