Eu tenho um caso de usuário comum quando transformo alguma expressão python da seguinte maneira:
value 1
value 2
value 3
para dentro
['value 1', 'value 2', 'value 3']
A maneira mais fácil pode ser usar um mapeamento, mas eu queria usar uma substituição para esta tarefa.
Até agora eu tenho:
s/\(.*\n\)\+/[&]/g
Que resultam em
[value 1
value 2
value 3
]
Isso levanta uma questão, porque eu quero poder combinar o \(.*\)
, mas não \n
oe usar o resultado do correspondente dentro de a '...'
.
Você sabe como fazer isso?
regular-expression
replace
nobe4
fonte
fonte
:'<,'>s/\v(.*)\n/'\1', / | s/\v(.*), /[\1]/
Você pode transformar isso em um mapeamento visual:xnoremap ,x :s/\v(.*)\n/'\1', / <Bar> s/\v(.*), /[\1]/<CR>
e talvez em um mapeamento normal, se o A expressão está dentro de um parágrafo:nnoremap ,x :'{+1,'}-1s/\v(.*)\n/'\1', / <Bar> s/\v(.*), /[\1]/<CR>
aqui estaria o mapeamento,x
.:%! echo "[$(sed "s/.*/'&',/" % | tr '\n' ' ' | sed 's/, $//')]"
Respostas:
Editar
É possível fazer isso em uma expressão se usarmos uma "sub-substituir-expressão". Veja abaixo para obter informações sobre isso.
/Editar
O problema aqui é que você deseja fazer duas coisas diferentes.
Opere a partida como um todo (ex .: envolva-a com
[]
)Opere em cada item da partida (ex .: envolva-os com
'',
)Você pode facilmente fazer qualquer um:
:s/\(.\+\n\)\+/[&]/
:%s/\(.\+\)\n/'\1', /
mas, tanto quanto sei, não há como fazer as duas coisas em uma única operação. Eu tentei obter a saída adequada com algo como:
Mas é claro que o problema disso é que as
\2
correspondências apenas a última correspondência do segundo conjunto de parênteses de memória\(\)
e não "lembram" nada antes disso. Então você acaba com apenas a última linha.Eu recomendaria fazer um pré / pós-processamento com um
:s///
comando adicional para se livrar das novas linhas antes / depois do fato. Aqui está o que eu vim com1ª linha (Remover novas linhas)
.,/\n^$/
Este é um modificador de intervalo para a pesquisa e substituição. Sem isso, o comando continuará mutilando seu arquivo inteiro. Atualmente, passa da linha atual.
para a próxima linha em branco\n^$
. Não tenho certeza de como você pretendia dividir as coisas, mas você precisa de uma maneira de dizer para parar.s/
O início de um comando de pesquisa e substituição\(.*\)\n
Corresponda a linha inteira, mas salve a peça apenas sem a nova linha.'\1',
Substitua a linha pela correspondência entre aspas simples e acrescente uma vírgula.2ª linha (entre parênteses)
\(.*\),
Corresponda a linha inteira, mas não a última vírgula e espaço[\1]
Coloque entre parênteses e também remova vírgula e espaço supérfluos.Vou continuar investigando isso, mas no momento não acho que seja possível com uma única expressão. :(
EDITAR:
Eu encontrei uma maneira de fazer isso com uma expressão! Internamente, na verdade, são duas substituições, mas tecnicamente é uma expressão. Aqui está o que eu vim com:
:s///
: Fazer uma substituição\v((.+\n)*.+)\n
: Basicamente reúne todas as próximas linhas não em branco e armazena tudo, exceto a final\n
\=
Permite usar uma expressão na substituição (consulte:h sub-replace-expression
)substitute(submatch(1)...)
: Substitui todos os armazenados\n
por', '
"['" . ... . "']"
: Anexa['
e anexa']
Isso começará na posição do cursor e continuará até encontrar uma linha em branco (
^\n
). Não agarrar o último\n
é importante, pois sem esse pedaço ficamos com um adicional',
que não queremos no final.Alguns podem considerar isso mais complexo do que a resposta de duas expressões anterior. Mas pensei em ir em frente e adicionar isso, já que é de fato possível fazê-lo com uma expressão. :)
fonte
Destaque visualmente, então:
Ele circunda cada linha, para fazer
['value 1']
, por exemplo , une todas elas, depois substitui as adjacentes]
e[
por vírgula.A documentação para o
*
in*j!
é:help cpo-star
, a propósito. Isso é um pouco difícil de encontrar.fonte
:'<,'>s/\v(.*)(\_.)/['\1']/
e remover a união.\n
, é por isso que eu usei:join
. Eu provavelmente deveria ter mencionado isso. :-)'<,'>s/.*/['&']/ | *s/]\_.\[/, /
então?*s/]\n\[/, /e
.