Bạn có thể sử dụng lệnh :s
với biểu thức phụ thay thế là \=
.
:s#\v^\s*\S+\zs(\s+)(.{-})(\s+)\ze\S+\s*$#\=substitute(submatch(1).submatch(3),'\v^(\s*)(\1\s=)$','\1'.escape(submatch(2),'~&\').'\2','')#
Tổng quan
Chụp văn bản (bao gồm màu trắng-không gian) giữa >>>
và <<<
dấu. Chia không gian trắng trên cả hai mặt của văn bản thành một nửa và thay thế trong văn bản không phải khoảng trắng ở giữa. Hành động cân bằng trắng không gian này được thực hiện thông qua backtracking của động cơ regex bởi vì toán học là khó. Chúng ta hãy đi mua sắm!
Ghi chú:
- sử dụng
\v
hoặc very magic
chế độ để giảm thoát như lệnh này là đủ lâu đã
- sử dụng
#
như một tách thay thế thay vì thông thường /
cho :s/pat/sub/
với hy vọng để làm cho nó một chút dễ đọc hơn
Mẫu phù hợp
:s#\v^\s*\S+\zs(\s+)(.{-})(\s+)\ze\S+\s*$#...
:s
không có phạm vi cung cấp chỉ làm sự thay thế trên dòng hiện tại.
^\s*\S+
khớp với khoảng trắng bắt đầu theo sau là khoảng trống trắng. >>>
trong trường hợp này.
(\s+)(.{-})(\s+)
khớp với khoảng trắng, theo sau là "văn bản" theo sau là khoảng trắng
- 3 nhóm chụp: 1) khoảng trắng đầu, 2) "văn bản" và 3) dấu cách trắng. Những sau đó sẽ được tham chiếu bởi
submatch(1)
, submatch(2)
, và submatch(3)
tương ứng
.{-}
được vim-nói cho phù hợp không tham lam hay .*?
trong perl-nói
- mà không có sự phi tham lam phù hợp với nhóm chụp thứ hai sẽ bao gồm quá nhiều màu trắng -space lúc kết thúc của nó
\S+\s*$
trận đấu không phải da trắng không gian (ví dụ: <<<
) và bất kỳ đuôi trắng-không gian
- Sử dụng
\zs
và ze
để chỉ sự bắt đầu và kết thúc của trận đấu phải được thay thế
Thay
\=substitute(submatch(1).submatch(3),'\v^(\s*)(\1\s=)$','\1'.escape(submatch(2),'~&\').'\2','')
\=
nói vim mà thay thế sẽ là một biểu thức vim. Cũng cho phép việc sử dụng các chức năng submatch()
substitute({str}, {pat}, {sub}, {flags})
biểu hiện của chúng tôi sẽ là một lồng nhau thay
substitute(submatch(1).submatch(3), ...)
làm một sự thay thế trong vòng nối của đầu và đuôi trắng khoảng cách bị bắt trong submatch(1)
và submatch(3)
- Các
{pat}
là ^(\s*)(\1\s=)$
. Phù hợp với một số khoảng trắng, theo sau là khoảng trắng có cùng chiều dài với ký tự đầu tiên hoặc dài hơn 1 ký tự. Chụp cả hai nửa.
escape(submatch(2),'~&\')
thoát submatch(2)
cho bất kỳ ký tự đặc biệt nào. ví dụ. ~
, &
, \1
, ...
{sub}
là '\1'.escape(submatch(2),'~&\').'\2'
. Thay thế bằng số thoát submatch(2)
(tức làcác "văn bản" chúng tôi muốn đến trung tâm) ở giữa nửa của màu trắng-không gian, \1
và \2
từ {pat}
- Không
{flag}
's là cần thiết để ''
Cách sử dụng
Nếu bạn sử dụng thường xuyên này tôi sẽ đề nghị tạo một lệnh và đặt nó trong ~/.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','')#`
Nếu không, hãy sử dụng điều này một lần và sau đó lặp lại thay thế cuối cùng qua &
trên mỗi dòng cần thiết.
Để được trợ giúp nhiều hơn thấy
:h :s/
:h :s/\=
:h sub-replace-\=
:h submatch(
:h substitute(
:h escape(
:h /\v
:h /\S
:h /\{-
:h /\zs
:h &
EDIT bởi Kent
Đừng ghen tuông, câu trả lời của bạn có nó quá.^_^
Tôi không thay đổi lệnh, chỉ cần cp/paste vào vim của tôi. chỉ thêm |noh
ở cuối để tắt đánh dấu.
Nếu thực hiện lệnh này, nó trông giống như:

Có chiều rộng cố định? – jcbwlkr
Bạn đã thử gì? – romainl
@ jacobwalker0814 Không có chiều rộng cố định. romainl: Tôi đã thử ': trung tâm trợ giúp' và tìm các plugin nhưng đối với một tác vụ đơn giản như vậy, plugin sẽ xuất hiện quá mức cần thiết. – Jens