grep: caractere especial '+'

5

Eu fiz alguns testes simples com grep '+' e '*' caractere especial

$ echo 'where wh+'> /tmp/toto
$ grep 'wh[e]\*' /tmp/toto
$ grep 'wh[e]*' /tmp/toto
where wh+
$ grep 'wh[e]+' /tmp/toto
$ grep 'wh+' /tmp/toto
$ grep 'wh[e]\+' /tmp/toto
where
$ grep -E 'wh[e]*' /tmp/toto
where wh+
$ grep -E 'wh[e]+' /tmp/toto
where wh+

A partir desses testes, o grep não estendido '+' (e '?') não é interpretado como um caractere especial; para usá-lo como um caractere especial, ele deve ser escapado. Enquanto eu leio, o grep usa Basic Regular Expressions (sem a opção -E), neste caso, caracteres especiais são definidos aqui: link e '? '+' não são caracteres especiais para BRE.

Mas por que o escape de um caractere não especial '+' em um BRE torna esse caractere especial?

    
por rem 11.05.2016 / 10:44

3 respostas

7

Esta é uma extensão do GNU. Na grep(1) manpage :

In GNU grep, there is no difference in available functionality between basic and extended syntaxes. In other implementations, basic regular expressions are less powerful. The following description applies to extended regular expressions; differences for basic regular expressions are summarized afterwards.

e mais abaixo

Basic vs Extended Regular Expressions

In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \).

    
por 11.05.2016 / 11:04
0

Eu não vejo bem qual dos exemplos acima para você parece violar o comportamento definido?

Nenhum escape de + altera as regras.

    
por 11.05.2016 / 11:08
0

Nesse link para a especificação POSIX que você forneceu, você pode ler:

An ordinary character is a BRE that matches itself: any character in the supported character set, except for the BRE special characters listed in BRE Special Characters.

The interpretation of an ordinary character preceded by a ( '\' ) is undefined, except for:

  • The characters ')', '(', '{', and '}'
  • The digits 1 to 9 inclusive (see BREs Matching Multiple Characters)
  • A character inside a bracket expression

Então, basicamente, como + é um caractere BRE comum, o comportamento de grep 'x\+' não é especificado, algumas implementações como GNU grep tratam o mesmo que grep 'x\{1,\}' ( grep -E 'x+' ), algumas o mesmo que grep 'x+' alguns podem tratar é o mesmo que grep 'x\+' ou qualquer outra coisa.

Portanto, se você quiser corresponder a string x\+ portably, deverá escrever grep 'x\+' (ou grep 'x[\]+' , ou grep -F 'x\+' ou grep -E 'x\\+' ou grep -E 'x[\][+]' ).

    
por 11.05.2016 / 11:30

Tags