Vim equivalente all'espressione regolare Perl per fare una sostituzione in una sostituzione?
Ho questa regex perl:
s/(^(#+)\s.*?\g2)/$1 =~ s|\n| |rg/gmse
Elimina tutte le nuove linee tra i ##+personaggi e le sostituisce con uno spazio. Ci vorrà una stringa come:
before text
more text
### hjh jh ja jhjasdhf jh'j
asdk kas dkjakdjf kasjd fkjasdkfj
kajsdkjf kasjdf end ###
after text
e modificalo in:
before text
more text
### hjh jh ja jhjasdhf jh'j asdk kas dkjakdjf kasjd fkjasdkfj kajsdkjf kasjdf end ###
after text
Voglio fare lo stesso con vim. Ho scoperto che posso usare \=per trasformare il lato destro in un'espressione, ma come faccio a eseguire una sostituzione sul valore di \ 1 e stamparla?
%s/\v(^(#+)\s.*?\g2)/\= WHAT GOES HERE?/g
Risposte
È possibile utilizzare la substitute()funzione per eseguire una sostituzione del testo sul lato di sostituzione di un :scomando. E puoi utilizzare submatch()per avere accesso ai gruppi abbinati, anche submatch(0)per l'intera partita.
È inoltre necessario utilizzare la sintassi Vim corretta per la regex, che differisce dalla sintassi Perl in alcuni modi. Dovresti usare {-}invece di *?per una ripetizione non avida, \2invece di \g2abbinare la stessa identica stringa abbinata nel gruppo 2, e devi anche \_.abbinare qualsiasi carattere incluso il ritorno a capo.
In realtà, poiché puoi usare la corrispondenza completa, non hai bisogno del gruppo di cattura esterno, quindi puoi sbarazzarti anche di quel set di parentesi e usarlo \1per abbinare la sequenza di #s.
Mettere tutto insieme:
:%s/\v^(#+)\s\_.{-}\1/\=substitute(submatch(0), '\n', ' ', 'g')/
Nel caso in cui si volessero unire le righe e si usassero solo espressioni regolari perché è la scelta "naturale" in Perl, c'è un altro modo in Vim. Puoi combinare il :globale il :joincomando per unire tutte le linee tra due sequenze di hash:
g/#\+/;/#\+/ join