การพับตามรูปแบบการค้นหาของ regex


13

ฉันได้รับไฟล์ข้อความธรรมดาที่มีคอลัมน์ค่าช่องว่างคั่น แบบนี้:

AU 3030 .... ... ....  
AU 3031 .... ... ....  
AU 3032 .... ... .... 
AU 3033 .... ... .... 
IT 48100 ... .. .....
IT 40100 ... .. .....
IT 48123 ... .. .....
UK 3333 ... ... ..... 
UK 4444 ... ... .....
UK 5555 ... ... .....

ฉันยังได้ regex นี้ซึ่งจะตรงกับบรรทัดที่อยู่ติดกันใด ๆ ที่มีค่าเดียวกันในคอลัมน์แรก (ถือว่าไฟล์จะถูกจัดเรียงในคอลัมน์แรก) ยกเว้นสุดท้าย:

/^\(\([A-Z0-9]\+\)\s\+.*\n\)\(\2\)\@=

(หรือทำให้น้อยลง "มีขนดก"):

/^\v([A-Z0-9]+)\s+.*\n(\1)@=

เป็นไปได้ไหมที่จะพับครึ่งบรรทัดที่ไม่ตรง? มีผลลัพธ์นี้:

+-- 4 lines AU ....
+-- 3 lines IT ....
+-- 3 lines UK ....

คำตอบ:


14

ทำset foldmethod=exprและใช้'foldexpr'เพื่อตั้งค่านิพจน์สคริปต์กลุ่มที่จะกำหนดจุดเริ่มต้นการพับ

set foldmethod=expr
set foldexpr=get(split(getline(v:lnum-1)),0,'')!=get(split(getline(v:lnum)),0,'')?'>1':'='

สิ่งนี้ดูซับซ้อนกว่าที่เป็นเพราะเราไม่สามารถใช้ช่องว่างได้ง่าย:setแต่ด้วยช่องว่างและขึ้นบรรทัดใหม่หรือ 2 ดูเหมือนว่า:

get(split(getline(v:lnum - 1)), 0, '') != get(split(getline(v:lnum)), 0, '')
    \ ? '>1'
    \ : '='

ภาพรวม

โดยทั่วไปสิ่งนี้จะเปรียบเทียบคำแรกของแต่ละบรรทัดกับบรรทัดก่อนหน้า >1หากคำที่มีความแตกต่างกันแล้วบรรทัดคือการเริ่มต้นของการพับ ไม่เช่นนั้นมันจะรักษาระดับการพับเหมือนเดิม, =.

ความรุ่งเรืองของรายละเอียด

  • set foldmethod=expr เพื่อบอกให้ Vim ใช้นิพจน์สคริปต์ vim เพื่อกำหนดการพับ
  • 'foldexpr' ตัวเลือกถือนิพจน์สคริปต์เป็นกลุ่ม
  • การประเมินสภาพด้วยไตรภาคที่ส่งกลับ>1เมื่อพับควรเริ่มต้นและ=เมื่อระดับการพับควรดำเนินการต่อ
  • v:lnumเป็นบรรทัดปัจจุบันที่'foldexpr'ใช้งานเพื่ออัปเดตการพับ
  • รับเนื้อหาบรรทัดปัจจุบัน ( v:lnum) และบรรทัดก่อนหน้า ( v:lnum - 1) ผ่านgetline()
  • แยกแต่ละบรรทัดออกเป็นคำทาง split()
  • ใช้get()เพื่อรับดัชนีแรกของคำที่แยกใหม่
  • ใช้ค่าเริ่มต้นเป็น''กรณีบรรทัดว่าง เช่นget(words, 0, '')
  • เปรียบเทียบคำแรกของบรรทัดปัจจุบันกับคำแรกของบรรทัดก่อนหน้าในส่วนเงื่อนไขของไตรภาค

หมายเหตุ: วิธีนี้อาจมีปัญหาประสิทธิภาพการทำงานกับเอกสารที่มีขนาดใหญ่มาก

สำหรับความช่วยเหลือเพิ่มเติมดู:

:h 'foldmethod'
:h 'foldexpr'
:h getline(
:h v:lnum
:h split(
:h get(
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.