Uma função compatível com posix para substituir texto por parâmetros e regex

5

Estou fazendo uma função com a substituição de strings usando expressões regulares de maneira segura, sem possibilidade de inserir caracteres e sem renunciar ao uso de expressões regulares:

#! /bin/sh

stringer()
{
    pattern="${1}"
    replace="${2}"

    printf '%s\n' "examp/e w\th sed: " | sed "s/${pattern}/${replace}/g"
}

stringer "\/" "l"

Até aí tudo bem, mas se eu usar:

stringer "/" "l"

resultaria em um erro sed, sobre isso eu sei que os parâmetros de entrada podem ser escapados, mas ele não poderia ser usado com expressões regulares, e eu quero poder usá-lo com regex, alguma sugestão com ou sem sed mas sem extensões para o modo posix-compliant?

    
por Emmett Brown 21.10.2017 / 20:21

1 resposta

8

Escapar do / somente é muito difícil de fazer com sed porque, por exemplo, ele teria que ser escapado em:

Foo/bar
Foo[XY]/
Foo\[/x\]
Foo\/bar

Mas não em

Foo [/x]bar
Foo [^]/x]bar
Foo [x[:blank:]/y]
Foo\/bar

Pode ser mais fácil usar awk

repl() {
  PATTERN=$1 REPL=$2 awk '
    {gsub(ENVIRON["PATTERN"], ENVIRON["REPL"]); print}'
}

No entanto, note que os expressões regulares do awk são expressões regulares estendidas (ao contrário das básicas no sed), e enquanto ele entende & na parte de substituição para significar a porção casada, não suporta o do sed. Exceto com o busybox awk, ele não suporta referências anteriores no padrão.

Aqui você pode seguir sua abordagem, mas documentar o fato de que / precisa ser escapado. Você precisará documentar quais são os operadores regexp de qualquer maneira (já que o usuário pode precisar escapar deles), que a nova linha não pode ser correspondida, e que essa nova linha deve ser escapada na substituição e o comportamento especial de & e backslash lá.

    
por 21.10.2017 / 21:41