Por que essas expressões regulares no grep se comportam de maneira estranha?

1

Eu queria brincar um pouco com o comando grep usando expressões regulares e descobrir que elas se comportam de maneira diferente do que eu esperava. Por exemplo, para um arquivo temp com o seguinte conteúdo

helloworld 
hello_world
hello world
hello how are you world
hello wor   ld
hello_*_..world 
helloEworld

quando eu corro

grep 'hello.*world' temp

retorna

helloworld 
hello_world
hello world
hello how are you world
hello_*_..world 
helloEworld

como esperado. Mas quando eu corro

grep 'hello.+world' temp

não retorna nada ... Embora quando adicionar \ antes de +

grep 'hello.\+world' temp

retorna a resposta correta

hello_world
hello world
hello how are you world
hello_*_..world 
helloEworld

ao adicionar \ antes de * no comando anterior e em execução

grep 'hello.\*world' temp

não retorna nada ...

Por que esse comando grep 'hello.+world' temp não funciona, enquanto que o \ funciona. E por que é exatamente o oposto para * ? Quando devo usar \ ?

    
por Myroslav 12.01.2015 / 16:00

1 resposta

4

Existem várias classes de expressões regulares que o GNU grep suporta:

  • Expressões regulares básicas (BRE) - o padrão. Não suporta + diretamente, mas suporta * . Você pode fazer com que + faça sentido quando escapar dela \+ . De documentação do GNU grep :

    In basic regular expressions the meta-characters ‘?’, ‘+’, ‘{’, ‘|’,
    ‘(’, and ‘)’ lose their special meaning; instead use the backslashed
    versions ‘\?’, ‘\+’, ‘\{’, ‘\|’, ‘\(’, and ‘\)’.
    
  • Expressões regulares estendidas (ERE) - a opção -E permite isso. Suporta + e * diretamente.

  • Expressões regulares compatíveis com Perl (PCRE) - a opção -P habilita o PCRE. Suporta sintaxe semelhante à do Perl, como lookaheads e lookbehinds.

BRE e ERE são geralmente classes padrão definidas por POSIX , então você deve encontrá-las em qualquer grep que aspira a compatibilidade POSIX e espera comportar-se de forma semelhante.

    
por muru 12.01.2015 / 16:05