Eu prefiro abordar esse tipo de coisa usando uma ferramenta que pode dividir a string usando um delimitador de vários caracteres. Você pode usar seu "padrão excluído" como delimitador e fazer substituições em elementos que não são o delimitador. Porque eu gosto de perl, eu vou fazer um perl one-liner aqui. :)
Primeiro, porque "perl" não foi uma das suas soluções sugeridas, acho que o perl não é algo em que você é strong. Então, vou começar com algumas coisas que você precisa saber sobre o perl para entender como isso funciona:
Se você colocar parens em torno do padrão de divisão na função perl split
, o separador será retido como um elemento adicional na matriz retornada por split
. Usar \[\[.*?\]\]
nos fornece a menor string contida entre [[
e ]]
, portanto, na matriz retornada, podemos selecionar elementos que não começam com [[
e fazem a substituição apenas nesses elementos. Com foreach e map, $ _ será uma referência (ponteiro) para o elemento da matriz, portanto, as alterações em $ _ alteram os elementos da matriz. Assim, depois de alterar a matriz, podemos unir os elementos potencialmente modificados e os delimitadores - ainda na ordem correta - de volta junto com os caracteres vazios. Além disso, gosto de usar unless()
, enquanto outras pessoas preferem if(!)
(mesmo com minha preferência de usar q{}
em vez de ''
, porque ''
parece com "
e ""
parece com ''''
;)). Isso não é golfe de código, e acho que é mais legível do meu jeito. :)
Ah, e caso isso também seja novo: perl -lne
- o -l
lida de forma transparente com novas linhas, o que eu acho que realmente não nos importamos aqui, mas é um hábito. O -n
coloca o código dentro de um while(<>){}
.
Com tudo isso dito, aqui está um exemplo funcional (sem sentido) substituindo cada não link "a" por "pie":
danny@host [/home/danny]
$ cat testfile
a b c d [[a]] b c d [[ moo a moo]] a
I like to eat [[meat]] on a plate
danny@host [/home/danny]
$ perl -nle'@l=split(/(\[\[.*?\]\])/); foreach (@l){s/a/pie/g unless(/^\[\[/)};
print join(q{}, @l)' testfile
pie b c d [[a]] b c d [[ moo a moo]] pie
I like to epiet [[meat]] on pie plpiete