Làm thế nào tôi có thể chạy: chỉ thay thế một phần của dòng và không phải tất cả của dòng?


15

Tôi có một dòng như thế này:

function my_function(argument, another argument, but there are spaces)

Tôi muốn thay thế các ký tự khoảng trắng (bên trong tên của đối số) bằng dấu gạch dưới. Vì vậy, tôi muốn sử dụng:

:s/\ /_/g

nhưng làm thế nào tôi có thể chọn không áp dụng nó cho toàn bộ dòng, nhưng bắt đầu từ vị trí con trỏ? (Hoặc từ thứ ba)?


4
Trong biểu thức chính quy, để mô tả vị trí con trỏ hiện tại, bạn có thể sử dụng nguyên tử \%#. Vì vậy, bạn có thể sử dụng : :s/\v(%#.*)@<= /_/g. Mà có thể được mô tả là khoảng trắng đứng trước @<=ký tự ( ) sau vị trí con trỏ.
dùng9433424

1
Cả bạn và Statox đều đề xuất \%#mánh khóe, tôi sẽ chấp nhận câu trả lời của anh ấy nếu bạn không viết một ... Nhưng một trong hai bạn có thể giải thích rõ hơn về biểu thức chính quy không?
Feffe

Câu trả lời:


15

Bạn có thể sử dụng giải pháp sau:

Đầu tiên sử dụng v$để chọn văn bản từ con trỏ đến cuối dòng. Sau đó sử dụng lệnh sau:

:s/\%V\ /_/g

Dấu \%Vhiệu để thay đổi văn bản trong khu vực được chọn trước đó, xem :h /\%V.

Nếu tôi lấy ví dụ của bạn:

function my_function(argument, another argument, but there are spaces)

Nếu con trỏ của tôi ở cột thứ 40 và tôi sử dụng lệnh tôi vừa viết, tôi nhận được:

function my_function(argument, another argument,_but_there_are_spaces)

Trả lời bình luận của bạn, bạn cũng có thể sử dụng

  • \%# khớp với vị trí con trỏ
  • \%>23c phù hợp sau cột thứ 23.
  • \%>'m phù hợp sau vị trí của một nhãn hiệu

Xem :h /\%#, :h /\%>c:h /\%>'m.

@ User9433424 đã đưa ra một cách để sử dụng \%#trong nhận xét của mình. Đối với mẫu có dấu bạn có thể đặt mẫu mađó rồi sử dụng:

:s/\%>'a /_/g

Giải thích về mẫu được đưa ra bởi @ User9433424 như sau:

:s/\v(%#.*)@<= /_/
:s/                    substitution command
   \v                  Enable the very magic mode
      %#.*             Any characters from the cursor position
           @<=         Check for matches just before what follows
              space    Followed by a space
               /_/     Substitute the matches by underscores

Bạn sẽ muốn xem :h \v:h /\@<=


Nó hoạt động tốt ! Nhưng tôi không thực sự quen với các lựa chọn trực quan và toàn bộ quá trình có vẻ hơi "nặng" ... Bạn có nghĩ rằng có thể có một cái gì đó nhanh hơn không?
Feffe

Có, hãy để tôi cập nhật câu trả lời của mình :)
statox

User9433424 đã đưa ra gợi ý này ngay trước bạn, nhưng bạn đã trả lời vì vậy tôi sẽ chấp nhận câu trả lời của bạn nếu điều đó ổn - bạn có thể giải thích mô hình regrec mà anh ấy sử dụng nhiều hơn một chút không? Tôi vẫn đang vật lộn với điều này ...
Feffe

Tôi đã cố gắng làm cho câu trả lời rõ ràng nhất có thể nhưng nếu @ User9433424 viết câu trả lời của chính mình, đừng ngần ngại chấp nhận nó.
statox

1
Lời giải thích rất hay của regrec, cảm ơn bạn! Và cảm ơn vì nhận xét của bạn về câu trả lời của ai để chấp nhận :)
Feffe

5

Bạn có thể sử dụng look đằng sau ( :h \@<=) để đảm bảo có một '(' và ranh giới cuối từ ( :h \>) trước để đảm bảo sự thay thế xảy ra ở nơi bạn muốn.

Vì vậy, với văn bản:

function my_function(argument, another argument, but there are spaces)

chạy lệnh:

:s/\((.*\)\@<=\> /_/g

sẽ sản xuất:

function my_function(argument, another_argument, but_there_are_spaces)

Điều này có thể dễ dàng hơn việc phải định vị con trỏ mỗi lần, với điều kiện thay thế luôn có điểm bắt đầu đã biết.


2
Sự thay thế không phải lúc nào cũng có điểm bắt đầu đã biết: nó chỉ để ... sửa một loạt lỗi chính tả kỳ lạ mà tôi đã tạo ra. Nhưng câu trả lời của bạn dù sao cũng thú vị, cảm ơn!
Feffe
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.