Bagaimana saya bisa menjalankan: mengganti hanya sebagian dari garis dan tidak semuanya?


15

Saya memiliki garis seperti ini:

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

Saya ingin mengganti karakter spasi (di dalam nama argumen) dengan garis bawah. Dengan demikian saya ingin menggunakan:

:s/\ /_/g

tetapi bagaimana saya bisa memilih untuk tidak menerapkannya ke seluruh baris, tetapi mulai dari, katakanlah, posisi kursor? (Atau kata ketiga)?


4
Dalam regex, untuk menggambarkan posisi kursor saat ini, Anda dapat menggunakan atom \%#. Jadi, Anda bisa menggunakan: :s/\v(%#.*)@<= /_/g. Yang bisa digambarkan sebagai spasi diawali oleh ( @<=) karakter setelah posisi kursor.
— user9433424

1
Anda dan Statox sama-sama mengusulkan \%#trik, saya akan menerima jawabannya jika Anda tidak menulis satu pun ... Tapi bisakah kalian menjelaskan regexp dengan sedikit lebih eksplisit?
— Feffe

Jawaban:


15

Anda dapat menggunakan solusi berikut:

Pertama digunakan v$untuk memilih teks dari kursor ke akhir baris. Kemudian gunakan perintah berikut:

:s/\%V\ /_/g

The \%Vmengindikasikan untuk mengubah teks di daerah yang sebelumnya visual yang dipilih, lihat :h /\%V.

Jika saya ambil contoh Anda:

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

Jika kursor saya ada di kolom ke-40 dan saya menggunakan perintah yang baru saya tulis, saya dapat

function my_function(argument, another argument,_but_there_are_spaces)

Sebagai jawaban atas komentar Anda, Anda juga dapat menggunakan

  • \%# yang cocok dari posisi kursor
  • \%>23c yang cocok setelah kolom ke-23.
  • \%>'m yang cocok setelah posisi tanda

Lihat :h /\%#, :h /\%>cdan :h /\%>'m.

@ User9433424 memberi cara untuk digunakan \%#dalam komentarnya. Untuk pola dengan tanda, Anda dapat mengaturnya dengan akal madan kemudian menggunakan:

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

Penjelasan tentang pola yang diberikan oleh @ User9433424 adalah sebagai berikut:

: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

Anda akan ingin melihat :h \vdan:h /\@<=


Ini bekerja dengan baik! Tapi saya tidak terlalu terbiasa dengan pilihan visual dan keseluruhan prosesnya agak "berat" ... Apakah Anda pikir mungkin ada sesuatu yang lebih cepat?
— Feffe

Ya, izinkan saya memperbarui jawaban saya :)
— statox

User9433424 memberikan petunjuk ini tepat sebelum Anda, tetapi Anda menjawab jadi saya akan menerima jawaban Anda jika tidak apa-apa - bisakah Anda menjelaskan pola regexp yang ia gunakan sedikit lebih banyak? Saya masih berjuang dengan ini ...
— Feffe

Saya mencoba membuat jawabannya sejelas mungkin tetapi jika @ User9433424 menulis jawabannya sendiri jangan ragu untuk menerimanya.
— statox

1
Penjelasan yang sangat bagus dari regexp, terima kasih! Dan terima kasih atas komentar Anda yang jawabannya diterima :)
— Feffe

5

Anda dapat menggunakan tampilan di belakang ( :h \@<=) untuk memastikan ada '(', dan batas akhir kata sebelumnya :h \>) untuk memastikan substitusi terjadi di tempat yang Anda inginkan.

Jadi, dengan teks:

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

menjalankan perintah:

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

akan menghasilkan:

function my_function(argument, another_argument, but_there_are_spaces)

Ini mungkin lebih mudah daripada harus memposisikan kursor setiap kali, asalkan substitusi selalu memiliki titik awal yang diketahui.


2
Substitusi tidak selalu memiliki titik awal yang diketahui: itu hanya untuk ... memperbaiki serangkaian kesalahan ketik yang saya buat. Namun jawaban Anda tetap menarik, terima kasih!
— Feffe
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.