Anda perlu substitusi dengan negara. Saya ingat pernah memberikan (/ beberapa?) Solusi lengkap untuk masalah seperti ini pada SO.
Berikut ini cara lain untuk melanjutkan (1). Sekarang, saya akan melanjutkan ke 2 langkah:
- variabel dummy list yang saya butuhkan untuk trik kotor dan berbelit-belit yang akan saya pakai
- substitusi tempat saya memasukkan len array dummy ini yang saya isi pada setiap kejadian yang cocok.
Pemberian yang mana:
:let t=[]
:%s/#\zs\d\+\(\.\d\+\)\=\ze/\=len(add(t,1))/g
Jika Anda tidak terbiasa dengan regex, saya menggunakan :h /\zs
dan \ze
untuk menentukan sub-pola mana yang saya cocok, maka saya cocok dengan serangkaian digit yang mungkin diikuti oleh titik dan angka lainnya. Ini tidak sempurna untuk angka floating point, tetapi ini sudah cukup di sini.
Catatan: Anda harus membungkusnya dalam perintah + fungsi pasangan untuk antarmuka yang sederhana. Sekali lagi, ada contoh pada SO / vim (di sini , di sini , di sini ) Saat ini saya cukup tahu vim untuk tidak peduli tentang membungkus trik ini menjadi sebuah perintah. Memang saya akan dapat menulis perintah ini pada percobaan pertama, sementara saya akan mengambil beberapa menit untuk mengingat nama perintah.
(1) Tujuannya adalah untuk dapat mempertahankan keadaan di antara pergantian, dan untuk mengganti kejadian saat ini dengan sesuatu yang tergantung pada keadaan saat ini.
Berkat :s\=
kami dapat menyisipkan sesuatu yang dihasilkan dari perhitungan.
Tetap masalah negara. Baik kita mendefinisikan fungsi yang mengelola keadaan eksternal, atau kita memperbarui diri kita sendiri keadaan eksternal. Dalam C (dan bahasa terkait), kami bisa menggunakan sesuatu seperti length++
atau length+=1
. Sayangnya, dalam skrip vim, +=
tidak dapat digunakan di luar kotak. Itu perlu digunakan dengan :set
atau dengan :let
. Ini berarti :let length+=1
menambah angka, tetapi tidak mengembalikan apa pun. Kami tidak bisa menulis :s/pattern/\=(length+=1)
. Kami membutuhkan sesuatu yang lain.
Kami membutuhkan fungsi bermutasi. yaitu fungsi yang mengubah inputnya. Kami memiliki setreg()
, map()
, add()
dan mungkin lebih. Mari kita mulai dengan mereka.
setreg()
bermutasi register. Sempurna. Kita bisa menulis setreg('a',@a+1)
seperti pada solusi @Doktor OSwaldo. Namun, ini tidak cukup. setreg()
lebih merupakan prosedur daripada fungsi (bagi mereka yang tahu Pascal, Ada ...). Ini berarti tidak mengembalikan apa pun. Sebenarnya, itu mengembalikan sesuatu. Nominal exit (yaitu pintu keluar non-pengecualian ) selalu mengembalikan sesuatu. Secara default, ketika kami lupa mengembalikan sesuatu, 0 dikembalikan - ini juga berlaku dengan fungsi bawaan . Itu sebabnya dalam solusinya ekspresi pengganti sebenarnya \=@a+setreg(...)
. Tricky, bukan?
map()
bisa juga digunakan. Jika kita mulai dari daftar dengan satu 0 ( :let single_length=[0]
), kita bisa menambahkannya berkat map(single_length, 'v:val + 1')
. Maka kita perlu mengembalikan panjang baru. Tidak seperti setreg()
, map()
mengembalikan input yang dimutasi. Itu sempurna, panjangnya disimpan pada posisi pertama (dan unik, dan juga terakhir) dari daftar. Ekspresi pengganti bisa \=map(...)[0]
.
add()
adalah salah satu yang sering saya gunakan karena kebiasaan (saya baru saja map()
benar - benar tahu, dan saya belum menentukan penampilan masing-masing). Gagasannya add()
adalah menggunakan daftar sebagai kondisi saat ini, dan menambahkan sesuatu di akhir sebelum setiap penggantian. Saya sering menyimpan nilai baru di akhir daftar, dan menggunakannya untuk penggantian. Seperti add()
juga kembali daftar masukan bermutasi, kita bisa menggunakan: \=add(state, Func(state[-1], submatch(0)))[-1]
. Dalam kasus OP, kita hanya perlu mengingat berapa banyak kecocokan yang terdeteksi sejauh ini. Mengembalikan panjang daftar negara ini sudah cukup. Karena itu saya \=len(add(state, whatever))
.
perldo
, Anda dapat menggunakan:%perldo s/#\K\d+(\.\d+)?/++$i/ge