Por que alguns comandos regex têm interpretações opostas de '\' com vários caracteres?

10

Tome, por exemplo, este comando:

find . -regex ".*\.\(cpp\|h\)"

Isso encontrará todos os arquivos .h e .cpp no ​​seu diretório. O caractere de ponto '.' em expressões regulares geralmente significa "qualquer caractere". Para que ele corresponda apenas a um período real, você deve escapá-lo usando o caractere de barra invertida '\'.

Nesse caso, dado um personagem com um significado especial, você deve escapar dele para obter o caractere real que ele representa.

Agora, pegue o parêntese e a barra "ou", sendo os caracteres '(', ')' e '|', respectivamente. Eles também têm significados especiais, usados ​​para agrupar expressões regulares. No entanto, para obter um significado especial, os caracteres devem ser escapados usando a barra invertida! Sem a barra invertida, os caracteres têm o significado do caractere real que ele representa.

Porque é o '.' tratado de forma diferente de '(', ')' e '|'?

Cory Klein
fonte

Respostas:

12

A resposta é realmente "apenas porque". Há várias sintaxes de expressões regulares diferentes e, embora elas compartilhem uma aparência semelhante e, geralmente, o básico seja o mesmo, elas variam de particular.

Historicamente, cada ferramenta tinha sua própria nova implementação, fazendo o que o autor pensava melhor. Há um equilíbrio entre tornar os personagens especiais com e sem escapar - muitos personagens que são "naturalmente especiais" e você acaba tendo que escapar deles o tempo todo apenas para combinar com eles; ou, por outro lado, você acaba precisando de várias fugas para usar a sintaxe regex comum, como o agrupamento (). E todos que escreviam um programa decidiram como fazê-lo com base nas necessidades das quais o programa correspondia, no que consideravam a abordagem correta e na fase da lua.

Há uma tentativa de padronização do POSIX, que define " expressões regulares básicas " e " expressões regulares estendidas ". Surpreendentemente, eles funcionam inversamente em relação a \- às vezes , mas não com perfeita consistência.

As expressões regulares do Perl tornaram-se outro padrão padrão, por duas razões: primeiro, são muito flexíveis e poderosas e, segundo, são realmente muito sãs , com convenções como "\ sempre escapa de um caracter não alfanumérico".

O GNU Find tem uma -regextypeopção, onde você pode alterar a sintaxe da expressão regular usada. Infelizmente, "perl" não é uma opção, pelo menos na versão do find que eu tenho. (O padrão é, sem surpresa do GNU, "emacs", e essa sintaxe está documentada aqui .)

mattdm
fonte