Por que o '?' personagem regex produz uma partida em sed? [duplicado]

4

Eu tenho uma string semelhante a ../../sdd1 e tentando corresponder a sdd daqui. Estou tentando usar o seguinte comando sed :

echo "../../sdd1" | sed 's:.*\([a-z]\{3\}\)[0-9]?::' 

e não produz correspondência.
Mas quando eu uso

echo "../../sdd1" | sed 's:.*\([a-z]\{3\}\)[0-9]\{0,1\}::'

depois recebo minha correspondência, sdd .

Meu melhor palpite é que eu escape também do ? , parecido com as chaves - tentei e funciona, mas não sei por quê.

Portanto, a pergunta é: por que a [0-9]? regex não corresponde à 1 de sdd1 ou por que precisamos escapar da ? e das chaves?

    
por mazs 06.07.2017 / 10:16

1 resposta

12

Por padrão, sed usa o BRE e precisa da opção -E ou -r para usar o ERE

Citações de manual do GNU sed

In GNU sed the only difference between basic and extended regular expressions is in the behavior of a few special characters: ‘?’, ‘+’, parentheses, braces (‘{}’), and ‘|’.

With basic (BRE) syntax, these characters do not have special meaning unless prefixed backslash (‘\’); While with extended (ERE) syntax it is reversed: these characters are special unless they are prefixed with backslash (‘\’).

então, para GNU sed , use

$ echo '../../sdd1' | sed 's:.*\([a-z]\{3\}\)[0-9]\?::'
sdd
$ echo '../../sdd1' | sed -E 's:.*([a-z]{3})[0-9]?::'
sdd

para POSIX BRE , seu segundo comando é o caminho a seguir

$ echo '../../sdd1' | sed 's:.*\([a-z]\{3\}\)[0-9]\{0,1\}::'
sdd
    
por 06.07.2017 / 12:08