É sed \ {x, y \} gama gulosa?

6

Gostaria de saber se, por exemplo, \{x,y\} in sed tentará corresponder o máximo possível de caracteres.

Além disso, alguém pode me explicar o comportamento inesperado abaixo de sed ?

echo "baaab" | sed 's/a\{1,2\}//'
bab

echo "baaab" | sed 's/a\{0,2\}//'
baaab

Na primeira linha, sed se torna ganancioso, no segundo, aparentemente, não, há uma razão para isso?

Estou usando o GNU sed versão 4.2.1.

    
por Kira 19.11.2015 / 01:00

2 respostas

15

a\{0,2\} corresponderá à string vazia no início da linha (na verdade, qualquer string vazia, mas g não foi especificado):

$ echo "baaab" | sed 's/a\{0,2\}/y/' 
ybaaab

Como o% GNUsed faz correspondência da esquerda para a direita e não foi especificado um substituto global, apenas o início da linha foi correspondido. Se você usou g :

$ echo "baaab" | sed 's/a\{0,2\}/y/g'
ybyyby

As strings vazias no início e no final correspondem, e o aa e o restante a .

    
por 19.11.2015 / 01:13
6

Sim, é ganancioso.

No sistema compatível com POSIX, não apenas sed , mas também todas as ferramentas que usam Expressão regular básica , o padrão sempre será ganancioso :

The search for a matching sequence starts at the beginning of a string and stops when the first sequence matching the expression is found, where "first" is defined to mean "begins earliest in the string". If the pattern permits a variable number of matching characters and thus there is more than one such sequence starting at that point, the longest such sequence is matched. For example, the BRE "bb*" matches the second to fourth characters of the string "abbbc", and the ERE "(wee|week)(knights|night)" matches all ten characters of the string "weeknights".

Consistent with the whole match being the longest of the leftmost matches, each subpattern, from left to right, shall match the longest possible string. For this purpose, a null string shall be considered to be longer than no match at all. For example, matching the BRE "(.)." against "abcdef", the subexpression "()" is "abcdef", and matching the BRE "(a*)*" against "bc", the subexpression "()" is the null string.

O padrão a\{0,2\} correspondeu a qualquer ocorrência de caractere a entre zero e dois. Ocorrência zero significa a string vazia, que é considerada mais longa do que nenhuma correspondência como a especificação indicada acima.

O problema com seu uso é que você não usou o sinalizador g lobal para o comando sed s ubstitution. Sem o sinalizador g lobal, sed parará de fazer s ubstitution assim que encontrar a primeira correspondência, que é a string vazia no começo da linha.

A forma geral é \{m,n\} com 0 <= m <= n <= RE_DUP_MAX , com RE_DUP_MAX é 32767 na maioria das plataformas:

$ getconf RE_DUP_MAX
32767
    
por 19.11.2015 / 03:25