คุณต้องทดแทนด้วยสถานะ ฉันจำได้ว่าได้ให้โซลูชันที่สมบูรณ์ (/ หลายรายการ) สำหรับปัญหาประเภทนี้ใน SO
นี่เป็นอีกวิธีในการดำเนินการ (1) ตอนนี้ฉันจะดำเนินการใน 2 ขั้นตอน:
- ตัวแปรรายการหุ่นที่ฉันต้องการสำหรับเคล็ดลับสกปรกและซับซ้อนที่ฉันจะจ้าง
- การแทนที่ที่ฉันแทรก len ของอาร์เรย์จำลองนี้ที่ฉันเติมในแต่ละเหตุการณ์ที่ตรงกัน
ซึ่งจะช่วยให้:
:let t=[]
:%s/#\zs\d\+\(\.\d\+\)\=\ze/\=len(add(t,1))/g
หากคุณไม่คุ้นเคยกับกลุ่ม regexes ฉันจะใช้:h /\zs
และ\ze
ระบุรูปแบบย่อยที่ฉันกำลังจับคู่อยู่จากนั้นฉันจับคู่ชุดตัวเลขที่อาจตามด้วยจุดและตัวเลขอื่น ๆ นี่ไม่เหมาะสำหรับเลขทศนิยมใด ๆ แต่นี่ก็เพียงพอแล้ว
หมายเหตุ: คุณจะต้องสรุปในฟังก์ชั่นคู่ + คำสั่งสำหรับอินเตอร์เฟซที่เรียบง่าย อีกครั้งมีตัวอย่างในดังนั้น / กลุ่ม ( ที่นี่ , ที่นี่ , ที่นี่ ) ปัจจุบันฉันรู้มากพอที่จะเป็นกลุ่มที่จะได้ดูแลเกี่ยวกับการตัดเคล็ดลับนี้ลงในคำสั่ง แน่นอนฉันจะสามารถเขียนคำสั่งนี้ได้ในการลองครั้งแรกในขณะที่ฉันจะใช้เวลาหลายนาทีในการจดจำชื่อของคำสั่ง
(1) วัตถุประสงค์คือเพื่อให้สามารถรักษาสถานะในระหว่างการแทนที่และเพื่อแทนที่เหตุการณ์ปัจจุบันด้วยสิ่งที่ขึ้นอยู่กับสถานะปัจจุบัน
ขอขอบคุณที่:s\=
เราสามารถแทรกสิ่งที่เกิดจากการคำนวณ
ยังคงเป็นปัญหาของรัฐ เราอาจกำหนดฟังก์ชันที่จัดการสถานะภายนอกหรือเราอัพเดตสถานะภายนอก ใน C (และภาษาที่เกี่ยวข้อง) เราอาจจะมีบางสิ่งบางอย่างที่ใช้เหมือนหรือlength++
length+=1
น่าเสียดายที่ในกลุ่มสคริปต์+=
ไม่สามารถใช้งานได้นอกกรอบ จะต้องมีการใช้ทั้งที่มีหรือ:set
:let
ซึ่งหมายความว่าจะ:let length+=1
เป็นการเพิ่มจำนวน แต่จะไม่ส่งคืนสิ่งใด :s/pattern/\=(length+=1)
เราไม่สามารถเขียน เราต้องการสิ่งอื่น
เราต้องการฟังก์ชั่นการกลายพันธุ์ ฟังก์ชั่นคือการเปลี่ยนแปลงอินพุตของพวกเขา เรามีsetreg()
, map()
, add()
และอาจจะมากขึ้น เริ่มจากพวกเขากันก่อน
setreg()
เปลี่ยนแปลงการลงทะเบียน สมบูรณ์ เราสามารถเขียนได้setreg('a',@a+1)
ในโซลูชันของ @Doktor OSwaldo และยังไม่เพียงพอ setreg()
เป็นขั้นตอนมากกว่าฟังก์ชั่น (สำหรับคนที่รู้จัก Pascal, Ada ... ) ซึ่งหมายความว่าจะไม่ส่งคืนสิ่งใด จริงๆแล้วมันคืนบางสิ่งบางอย่าง การออกที่ระบุ (เช่นการออกที่ไม่ใช่ข้อยกเว้น ) จะส่งคืนบางสิ่งเสมอ ตามค่าเริ่มต้นเมื่อเราลืมส่งคืนบางสิ่งจะถูกส่งคืน 0 ซึ่งจะใช้กับฟังก์ชันในตัว \=@a+setreg(...)
นั่นเป็นเหตุผลในการแก้ปัญหาของเขาแสดงออกทดแทนที่เป็นจริง หากินใช่มั้ย
map()
ยังสามารถใช้ ถ้าเราเริ่มต้นจากรายการที่มีเพียงครั้งเดียว (0 :let single_length=[0]
) map(single_length, 'v:val + 1')
เราอาจจะเพิ่มขึ้นก็ต้องขอบคุณ จากนั้นเราต้องคืนค่าความยาวใหม่ ซึ่งแตกต่างsetreg()
, map()
ผลตอบแทนการป้อนข้อมูลกลายพันธุ์ของมัน นั่นคือความสมบูรณ์แบบความยาวจะถูกเก็บไว้ที่ตำแหน่งแรก (และไม่ซ้ำใครและจะคงอยู่เช่นกัน) ในรายการ \=map(...)[0]
การแสดงออกอาจจะมีการเปลี่ยน
add()
เป็นหนึ่งที่ผมมักจะใช้ออกมาจากนิสัย (ฉันได้เพียงแค่คิดเกี่ยวกับmap()
ความเป็นจริงและฉันไม่ได้ benched การแสดงของตนยัง) แนวคิดด้วยadd()
คือการใช้รายการเป็นสถานะปัจจุบันและเพื่อผนวกสิ่งที่อยู่ท้ายสุดก่อนการทดแทนแต่ละครั้ง ฉันมักจะเก็บค่าใหม่ที่ส่วนท้ายของรายการและใช้เพื่อทดแทน ขณะที่ยังส่งกลับรายการการป้อนข้อมูลของมันกลายพันธุ์เราสามารถใช้:add()
\=add(state, Func(state[-1], submatch(0)))[-1]
ในกรณีของ OP เราจะต้องจำได้ว่ามีการตรวจพบการแข่งขันกี่ครั้งแล้ว การคืนความยาวของรายการสถานะนี้ก็เพียงพอแล้ว \=len(add(state, whatever))
ดังนั้นฉัน
perldo
คุณสามารถใช้:%perldo s/#\K\d+(\.\d+)?/++$i/ge