:s
このコマンドは、\=
別名 sub-replace-expressionで使用できます。
:s#\v^\s*\S+\zs(\s+)(.{-})(\s+)\ze\S+\s*$#\=substitute(submatch(1).submatch(3),'\v^(\s*)(\1\s=)$','\1'.escape(submatch(2),'~&\').'\2','')#
概要
>>>
と<<<
マークの間のテキスト (空白を含む) をキャプチャします。テキストの両側の空白を半分に分割し、その間の空白以外のテキストに置き換えます。数学は難しいため、この空白のバランスをとる行為は、正規表現エンジンのバックトラッキングによって行われます。買い物に行きましょう!
ノート:
- このコマンドはすでに十分に長いため、
\v
またはモードを使用してエスケープを減らしますvery magic
- 少し読みやすくするために、通常のfor
#
の代わりに代替セパレータとして使用します/
:s/pat/sub/
マッチングパターン
:s#\v^\s*\S+\zs(\s+)(.{-})(\s+)\ze\S+\s*$#...
:s
範囲が指定されていない場合、現在の行でのみ置換が行われます。
^\s*\S+
非空白が続く最初の空白と一致します。>>>
この場合。
(\s+)(.{-})(\s+)
空白の後に「テキスト」が続き、その後に空白が続くものに一致
- 3 つのキャプチャ グループ: 1) 先頭の空白、2) 「テキスト」、および 3) 末尾の空白。これらは、後でそれぞれ
submatch(1)
、submatch(2)
、によって参照されます。submatch(3)
.{-}
非貪欲なマッチングのためのvim-speakまたは.*?
perl-speak
- 貪欲ではない一致がなければ、2 番目のキャプチャ グループの最後に空白が多すぎます。
\S+\s*$
非空白 (つまり<<<
) と末尾の空白に一致
\zs
とを使用しze
て、置換する一致の開始と終了を指定します
置換
\=substitute(submatch(1).submatch(3),'\v^(\s*)(\1\s=)$','\1'.escape(submatch(2),'~&\').'\2','')
\=
置換がvim式になることをvimに伝えます。submatch()
関数の使用も可能
substitute({str}, {pat}, {sub}, {flags})
私たちの式はネストされた置換になります
substitute(submatch(1).submatch(3), ...)
submatch(1)
とでキャプチャされた先頭と末尾の空白の連結を置換しますsubmatch(3)
{pat}
です^(\s*)(\1\s=)$
。_ 最初の文字と同じ長さまたは 1 文字長い空白が後に続く空白に一致します。両方の半分をキャプチャします。
escape(submatch(2),'~&\')
submatch(2)
特殊文字をエスケープします。例~
, &
, \1
, ...
{sub}
です'\1'.escape(submatch(2),'~&\').'\2'
。_ 空白submatch(2)
の半分の間、\1
および\2
{pat}
- いいえ
{flag}
は必要ありません''
使用法
これを頻繁に使用する場合は、コマンドを作成して に配置することをお勧めし~/.vimrc
ます。
command! -range -bar -nargs=0 CenterBetween <line1>,<line2>s#\v^\s*\S+\zs(\s+)(.{-})(\s+)\ze\S+\s*$#\=substitute(submatch(1).submatch(3),'\v^(\s*)(\1\s=)$','\1'.submatch(2).'\2','')#`
&
それ以外の場合は、これを 1 回使用してから、必要な各行で最後の置換を繰り返します。
詳細については、次を参照してください。
:h :s/
:h :s/\=
:h sub-replace-\=
:h submatch(
:h substitute(
:h escape(
:h /\v
:h /\S
:h /\{-
:h /\zs
:h &
ケントによる編集
嫉妬しないでください、あなたの答えにもそれがあります。^_^
コマンドは変更せず、vim に cp/paste するだけです。|noh
強調表示を無効にするために最後に追加するだけです。
このコマンドを実行すると、次のようになります。
