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

10

Tome, por exemplo, este comando:

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

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

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

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

Por que o '.' tratado diferentemente de '(', ')' e '|'?

    
por Cory Klein 17.02.2011 / 21:23

1 resposta

12

A resposta é realmente "só porque". Há um monte de sintaxes de expressões regulares diferentes e, embora compartilhem uma aparência semelhante e normalmente o básico seja o mesmo, elas variam nos detalhes.

Historicamente, toda ferramenta tinha sua própria implementação, fazendo o que o autor considerasse melhor. Há um equilíbrio entre fazer 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, ao contrário, você acaba precisando de um monte de escapes para usar o agrupamento like () de sintaxe de regex comum. E todos que escreveram um programa decidiram como fazê-lo com base nas necessidades do que o programa correspondia, no que consideravam ser a abordagem correta e na fase da lua.

Existe uma tentativa de padronização do POSIX, que define " expressões regulares básicas " e " expressões regulares estendidas ". Awesomely, estes trabalham para trás uns dos outros em relação a \ - às vezes , mas não com perfeita consistência.

Expressões regulares Perl tornaram-se outro padrão, por duas razões: primeiro, elas são muito flexíveis e poderosas, e segundo, elas são bem sãs , com convenções como "\ sempre escapa um caractere não alfanumérico ".

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

    
por 17.02.2011 / 21:42