ฉันจะรันได้อย่างไร: แทนที่ส่วนใดส่วนหนึ่งของบรรทัดและไม่ได้ทั้งหมด


15

ฉันมีเส้นแบบนี้:

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

ฉันต้องการแทนที่อักขระช่องว่าง (ภายในชื่ออาร์กิวเมนต์) ด้วยเครื่องหมายขีดล่าง ฉันต้องการใช้:

:s/\ /_/g

แต่ฉันจะเลือกที่จะไม่ใช้กับทั้งบรรทัดได้อย่างไร แต่เริ่มจากพูดตำแหน่งเคอร์เซอร์ (หรือคำที่สาม)?


4
ใน regex \%#เพื่ออธิบายตำแหน่งของเคอร์เซอร์ปัจจุบันคุณสามารถใช้อะตอม ดังนั้นคุณสามารถใช้: :s/\v(%#.*)@<= /_/g. ซึ่งสามารถอธิบายได้ว่าเป็นช่องว่างที่นำหน้าด้วย ( @<=) อักขระหลังตำแหน่งเคอร์เซอร์
user9433424

1
ทั้งคุณและ Statox เสนอ\%#เคล็ดลับฉันจะยอมรับคำตอบของเขาถ้าคุณไม่เขียน ... แต่คุณสามารถอธิบาย regexp ด้วยวิธีที่ชัดเจนกว่านี้ได้ไหม?
Feffe

คำตอบ:


15

คุณสามารถใช้วิธีแก้ไขปัญหาต่อไปนี้:

ใช้งานครั้งแรกv$เพื่อเลือกข้อความจากเคอร์เซอร์ไปที่ท้ายบรรทัด จากนั้นใช้คำสั่งต่อไปนี้:

:s/\%V\ /_/g

บ่งบอกถึงการเปลี่ยนข้อความในพื้นที่ก่อนหน้านี้เลือกทางสายตาให้ดู\%V:h /\%V

ถ้าฉันนำตัวอย่างของคุณ:

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

หากเคอร์เซอร์ของฉันอยู่ในคอลัมน์ที่ 40 และฉันใช้คำสั่งที่ฉันเพิ่งเขียนฉันจะได้รับ:

function my_function(argument, another argument,_but_there_are_spaces)

ในการตอบความคิดเห็นของคุณคุณสามารถใช้

  • \%# ซึ่งตรงจากตำแหน่งเคอร์เซอร์
  • \%>23c ซึ่งตรงกับหลังคอลัมน์ที่ 23
  • \%>'m ซึ่งตรงกับตำแหน่งของเครื่องหมาย

ดู:h /\%#, และ:h /\%>c:h /\%>'m

@ User9433424 ให้วิธีการใช้\%#ในความคิดเห็นของเขา สำหรับรูปแบบที่มีเครื่องหมายคุณสามารถตั้งค่าด้วยปัญญาmaแล้วใช้:

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

คำอธิบายของรูปแบบที่กำหนดโดย @ User9433424 มีดังต่อไปนี้:

: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

คุณจะต้องการที่จะเห็น:h \vและ:h /\@<=


มันใช้งานได้ดี! แต่ฉันไม่คุ้นเคยกับการเลือกภาพและกระบวนการทั้งหมดดูเหมือนว่า "หนัก" เล็กน้อย ... คุณคิดว่าอาจมีบางสิ่งที่เร็วกว่านี้ไหม
Feffe

ใช่ให้ฉันอัปเดตคำตอบของฉัน :)
statox

User9433424 ให้คำแนะนำนี้ก่อนคุณ แต่คุณตอบฉันจะยอมรับคำตอบของคุณถ้าไม่เป็นไร - คุณช่วยอธิบายรูปแบบ regexp ที่เขาใช้อีกหน่อยได้ไหม? ฉันยังคงดิ้นรนกับเรื่องนี้ ...
Feffe

ฉันพยายามทำให้คำตอบชัดเจนที่สุด แต่ถ้า @ User9433424 เขียนคำตอบของเขาเองอย่าลังเลที่จะยอมรับมัน
statox

1
คำอธิบายที่ดีมากของ regexp ขอขอบคุณ! และขอขอบคุณสำหรับความคิดเห็นของคุณมีคำตอบที่จะยอมรับ :)
Feffe

5

คุณสามารถใช้ดูด้านหลัง ( :h \@<=) เพื่อให้แน่ใจว่ามี '(') ก่อนหน้าและขอบเขตสิ้นสุดของคำ ( :h \>) เพื่อให้แน่ใจว่าการทดแทนเกิดขึ้นในตำแหน่งที่คุณต้องการ

ดังนั้นด้วยข้อความ:

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

ใช้คำสั่ง:

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

จะผลิต:

function my_function(argument, another_argument, but_there_are_spaces)

การดำเนินการนี้อาจง่ายกว่าการวางเคอร์เซอร์ในแต่ละครั้งหากการแทนที่มีจุดเริ่มต้นที่รู้จักเสมอ


2
การทดแทนไม่ได้มีจุดเริ่มต้นที่รู้จักกันเสมอ: มันเป็นเพียงเพื่อ ... แก้ไขชุดผิดแปลก ๆ ที่ฉันทำ แต่คำตอบของคุณก็น่าสนใจอยู่ดีขอบคุณ!
Feffe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.