2011-06-21 22 views
8

Câu hỏi này gần giống với this question ngoại trừ việc tôi phải đi đến ba khoảng trắng (hướng dẫn mã hóa công ty) thay vì bốn và giải pháp được chấp nhận sẽ chỉ tăng gấp đôi mẫu phù hợp. Đây là nỗ lực đầu tiên của tôi:Làm cách nào để định dạng lại tệp nguồn để chuyển từ 2 khoảng trống đến 3?

:%s/^\(\s\s\)\+/\1 /gc 

Nhưng điều này không hiệu quả vì bốn dấu cách được thay thế bằng ba dấu cách. Vì vậy, tôi nghĩ rằng những gì tôi cần là một số cách để đếm số lần mẫu khớp với dấu "+" và sử dụng số đó để tạo mặt khác của sự thay thế nhưng tôi cảm thấy chức năng này có lẽ không có sẵn trong regex của Vim (Hãy để tôi biết nếu bạn nghĩ rằng nó có thể là có thể).

Tôi cũng đã cố gắng làm việc thay thế bằng tay bằng cách thay thế indents lớn nhất đầu tiên và sau đó là thụt lề nhỏ hơn tiếp theo cho đến khi tôi đã nhận nó tất cả các chuyển đổi nhưng điều này thật khó để theo dõi các không gian:

:%s/^    \(\S\)/      \1/gc 

tôi có thể gửi nó thông qua Perl vì nó có vẻ như Perl có thể có khả năng làm điều đó với Extended Patterns của nó. Nhưng tôi không thể làm cho nó hoạt động với phiên bản Perl của tôi. Đây là nỗ lực của tôi với cố gắng để đếm của:

:%!perl -pe 'm<(?{ $cnt = 0 })(a(?{ local $cnt = $cnt + 1; }))*aaaa(?{ $res = $cnt })>x; print $res' 

phương sách cuối cùng của tôi sẽ viết một kịch bản Perl để làm việc chuyển đổi nhưng tôi đã hy vọng cho một giải pháp tổng quát hơn trong Vim để tôi có thể tái sử dụng các ý tưởng giải quyết các vấn đề khác trong tương lai.

+0

Có thể;) – Amadan

+0

Cảm ơn Amadan, được đánh dấu là câu trả lời đúng. Tôi tự hỏi liệu có ai đó có thể cho tôi xem giải pháp có thể trông như thế nào nếu nó được gửi qua Perl regex cũng như tôi có thể có dịp cần làm điều đó trong một tập lệnh không? – stephenmm

+0

Liên quan: [Re-indenting badly indented code] (http://vi.stackexchange.com/q/236/467) tại Vim SE – kenorb

Trả lời

7

Hãy để vim làm điều đó cho bạn?

:set sw=3<CR> 
gg=G 

Lệnh đầu tiên đặt tùy chọn shiftwidth, là số tiền bạn đã thụt vào. Dòng thứ hai cho biết: chuyển lên đầu tệp (gg) và quay lại (=) cho đến khi kết thúc tệp (G).

Tất nhiên, điều này phụ thuộc vào vim có trình định dạng tốt cho ngôn ngữ bạn đang sử dụng. Một cái gì đó có thể nhận được điều sai lầm nếu không.

biểu thức chính quy cách ... an toàn hơn, nhưng ít hiểu:

:%s#^\(\s\s\)\+#\=repeat(' ',strlen(submatch(0))*3/2)#g 

(tôi phải làm một số thí nghiệm.)

Hai điểm:

  • Nếu việc thay đổi bắt đầu với \= , nó được đánh giá là một biểu thức.
  • Bạn có thể sử dụng nhiều thứ thay vì /, vì vậy / có sẵn để chia.
+0

Công cụ chuyển đổi thực sự bị cắt xén tệp của tôi nhưng regex hoạt động hoàn hảo! Cảm ơn! Tôi đã cố gắng tìm kiếm sự giúp đỡ vim để tìm hiểu thêm về '\ =' nhưng tôi không chắc chắn những gì cần tìm trong trợ giúp. Bạn có thể chỉ cho tôi tài liệu nói về nó không? – stephenmm

+2

': help sub-replace-expression' – phant0m

+0

Có lệnh': retab'. – ZyX

1

Phiên bản perl bạn yêu cầu ...

Từ dòng lệnh (chỉnh sửa tại chỗ, không có dự phòng):

bash$ perl -pi -e 's{^((?: )+)}{" " x (length($1)/2)}e' YOUR_FILE 

(tại chỗ, ban đầu sao lưu vào " TẬP TIN CỦA BẠN.bak "):

bash$ perl -pi.bak -e 's{^((?: )+)}{" " x (length($1)/2)}e' YOUR_FILE 

Từ vim trong khi chỉnh sửa YOUR_FILE:

:%!perl -pe 's{^((?: )+)}{" " x (length($1)/2)}e' 

Các regex phù hợp với đầu dòng, tiếp theo (các thiết lập chụp của) một hoặc nhiều "" nhóm hai không gian. Mẫu thay thế là một biểu thức perl (do đó là công cụ sửa đổi 'e') đếm số lượng nhóm "hai không gian" đã được chụp và tạo một chuỗi có cùng số lượng nhóm "ba không gian" đó. hiện tại trong bản gốc nó được giữ nguyên sau khi thay thế. Vì vậy, nếu bạn có ba không gian trước đó, bạn sẽ có bốn sau, năm trước đó sẽ biến thành bảy sau, v.v.

+0

Công cụ tuyệt vời, cảm ơn Brian! – stephenmm

Các vấn đề liên quan