2010-06-04 25 views
7

Tôi có văn bản theo định dạng follwing:regex vim để thay thế khoảng trống bên trong dấu ngoặc kép

ERR_OUT_OF_MEM, "ERR OUT OF MEM" 
ERR_SOMETHING_BAD, "ERR SOMETHING BAD" 

Tôi muốn thay thế tất cả các không gian trong văn bản đó nằm trong dấu ngoặc kép với dấu gạch dưới:

ERR_OUT_OF_MEM, "ERR_OUT_OF_MEM" 
ERR_SOMETHING_BAD, "ERR_SOMETHING_BAD" 

tốt nhất regex Tôi có thể nghĩ ra là:

\("\w\+\)\@<= 

(có khoảng trống ở cuối)

nhưng điều này chỉ tìm thấy không gian đầu tiên trong mỗi chuỗi được trích dẫn và tôi sẽ cần phải lặp lại nhiều lần này để có được hiệu quả mong muốn.

Bất kỳ cách nào để thực hiện nó trong một lần phát?

Cảm ơn!

Trả lời

6

Có chắc chắn là một mô hình 0-chiều dài làm việc trong một vượt qua, nhưng như tôi đã không bao giờ có được nhiều thành công việc sử dụng chúng, tôi thích cách tiếp cận này:

:%s/\%("[^"]*"\)*\("[^"]*"\)/\=substitute(submatch(1), ' ', '_', 'g')/g 

Lưu ý: hai dấu ngoặc kép được giữ nhóm 2 bằng 2 để không biến đổi

foo bar "foo bar" "foo barr" 

vào

foo bar "foo_bar"_"foo_barr" 

EDIT: như rampion chỉ o ut, sau đây là quá đủ:

%s/"[^"]*"/\=substitute(submatch(0), ' ', '_', 'g')/g 
+0

Tại sao không chỉ cần sử dụng '/ "[^"] *"/'mẫu tôi không có được những gì bỏ qua các cặp báo giá ban đầu sẽ mua bạn (với '\% (" [^ "] *" \) * ') – rampion

+0

Điểm tốt. Tôi đã được thuyết phục rằng tìm kiếm sẽ bắt đầu lại không phải sau trích dẫn kết thúc, mà là sau phần mở đầu. Tôi sửa regex. Cảm ơn. –

6

Đây không phải là một giải pháp có mục đích chung, vì nó sẽ phù hợp với bất kỳ không gian xuất hiện ở bất cứ đâu sau một dấu nháy kép trên một dòng, nhưng nó phải làm việc cho chuỗi trong định dạng bạn đã chỉ định:

s/\v(\".*)@<= /_/g 

Tôi đã sử dụng mã thông báo \ v (verymagic) vì tôi nghĩ nó giúp regex dễ đọc hơn và tôi đã bao gồm toàn bộ lệnh thay thế, vì 'g' cuối cùng là quan trọng.

Đối với những người theo dõi ở nhà, trước tiên regex này đặt chế độ 'rất khắc nghiệt' với \ v. Sau đó, nó định nghĩa mã thông báo (\".*) có nghĩa là "một trích dẫn kép và sau đó bất kỳ điều gì khác" và sử dụng xác nhận lookbehind @<= để nói "chỉ khớp với những thứ sau mã thông báo cuối cùng" - nói cách khác, chỉ khớp với những thứ đến một nơi nào đó sau một dấu ngoặc kép . Cuối cùng, có một không gian, đó là những gì thực sự được so khớp, và thuật ngữ thay thế là dấu gạch dưới, đó là những gì chúng ta muốn thay thế nó, và g nói "thay thế tất cả các cụm từ phù hợp" để chúng ta không chỉ nhận được Trùng khớp.

+0

Điều này hoạt động, nhưng nó cũng thay thế các khoảng trống mà tôi có ở cuối dòng. –

+0

Ah. Có, nếu bạn có dấu cách, bạn sẽ cần một cách tiếp cận phức tạp hơn. Luc, ở trên, nên làm điều đó. –

0

My PatternsOnText plugin cung cấp lệnh :SubstituteInSearch. Với nó, bạn tìm kiếm đầu tiên cho chuỗi trích dẫn, sau đó thực hiện một :substitute chỉ trong các trận đấu:

/".\{-}" 
:SubstituteInSearch/_/ /g 
Các vấn đề liên quan