置換で置換を行うためのPerl正規表現と同等のVim?

Aug 25 2020

私はこのperl正規表現を持っています:

s/(^(#+)\s.*?\g2)/$1 =~ s|\n| |rg/gmse

##+文字間のすべての新しい行を取り除き、スペースに置き換えます。次のような文字列が必要です。

before text
more text
### hjh jh ja jhjasdhf jh'j
asdk kas dkjakdjf kasjd fkjasdkfj
kajsdkjf kasjdf end ###
after text

次のように変更します。

before text
more text
### hjh jh ja jhjasdhf jh'j asdk kas dkjakdjf kasjd fkjasdkfj kajsdkjf kasjdf end ###
after text

vimでも同じことをしたいです。\=右辺を式に変換するために使用できることを発見しましたが、\ 1の値を置換して出力するにはどうすればよいですか?

%s/\v(^(#+)\s.*?\g2)/\= WHAT GOES HERE?/g

回答

2 filbranden Aug 25 2020 at 03:33

このsubstitute()関数を使用して、:sコマンドの置換側でテキスト置換を実行できます。また、を使用submatch()してsubmatch(0)、試合全体を含め、試合したグループにアクセスできます。

また、正規表現には正しいVim構文を使用する必要があります。これは、いくつかの点でPerl構文とは異なります。グループ2で一致したまったく同じ文字列に一致する代わりに、貪欲でない繰り返しの{-}代わりに*?を使用する必要があります。また改行を含むすべての文字に一致する必要があります。\2\g2\_.

実際には、完全一致を使用できるため、外部キャプチャグループは必要ありません。そのため、その親のセットも削除し、を使用\1して#sのシーケンスを一致させることができます。

すべてを一緒に入れて:

:%s/\v^(#+)\s\_.{-}\1/\=substitute(submatch(0), '\n', ' ', 'g')/
4 JürgenKrämer Aug 26 2020 at 14:13

行を結合したいが、Perlの「自然な」選択であるために正規表現のみを使用した場合に備えて、Vimには別の方法があります。:global:joinコマンドを組み合わせて、2つのハッシュシーケンス間のすべての行を結合できます。

g/#\+/;/#\+/ join