Ingin melakukan pencarian dan mengganti file dengan 12000 baris.
Khususnya, jika kejadian ^ SetFontSize 28
ada setelah ^Hide
blok dan sebelum ^Hide
atau sesudahnya ^Show
, ubah 28
ke 18
.
Berikut cuplikan dari file asli.
Hide # Gear - Endgame
ItemLevel >= 77
Rarity = Magic
LinkedSockets >= 3
BaseType "Runic Hatchet"
SetTextColor 140 190 255 # Magic Item Highlight
SetFontSize 28
Hide # Gear - Endgame
ItemLevel >= 77
Rarity = Magic
Sockets >= 3
BaseType "Runic Hatchet"
SetTextColor 140 190 255 # Magic Item Highlight
SetFontSize 28
Show # Gear - Endgame
ItemLevel >= 83
Rarity = Normal
Sockets < 3
BaseType "Tiger Hook"
SetTextColor 240 240 240 # Normal Item Highlight
SetBackgroundColor 70 70 70
SetFontSize 28
Hasil akhir untuk salah satu Hide
blok akan terlihat seperti ini:
Hide # Gear - Endgame
ItemLevel >= 77
Rarity = Magic
LinkedSockets >= 3
BaseType "Runic Hatchet"
SetTextColor 140 190 255 # Magic Item Highlight
SetFontSize 18
Mengganti SetFontSize 28
ke SetFontSize 18
, tetapi hanya jika muncul di ^Hide
blok.
Regex jahat yang saya coba adalah:
:%s/^Hide\(.*\)SetFontSize 28$/Hide\1SetFontSize 18/g
Tetapi diberitahu pola tidak ditemukan. Harap beri tahu saya jika ada informasi tambahan yang diperlukan atau jika permintaan saya tidak jelas.
Hide
blok memilikiSetFontSize
garis (berapapun nilainya)? Jika demikian, Anda dapat menggunakan:%s/Hide\_.\{-\}SetFontSize \zs28/18/
whatever be the value
akan menyebabkan masalah, solusi Anda hanya berfungsi jika setiapHide
blok memilikiSetFontSize
garis dan nilainya tepat28
, jika tidak, cocok hingga28
blok lainnya.Jawaban:
Salah satu cara untuk mengatasi ini adalah dengan menggunakan
:global
yang menghasilkan output rentang.Penggunaan
global
perintah biasanyaIni juga memiliki opsi untuk membuat pola ini menghasilkan rentang daripada pencocokan garis tunggal dengan menggunakan
,
dalam bentukIni menghasilkan rentang yang diterapkan pada perintah.
Misalnya Anda pola pertama akan cocok dengan pertama
Hide
masuk dan pola kedua adalah baikHide
,Show
atau akhir file (dengan asumsi Anda ingin bahwa Hide kasus terakhir).Regex pertama sederhana
/Hide/
,. Regex kedua berisi beberapa bagian yang menarik.\(
dan\)
membuat pengelompokan atom yang cocok\|
adalah operasi ATAU\%$
mewakili akhir fileSetelah kami menentukan rentang kami, kami menerapkan pengganti dengan pola dan string seperti biasa.
Harap dicatat bahwa regex yang digunakan dalam contoh ini sangat mendasar. Anda akan ingin memastikan bahwa pengidentifikasi Anda untuk awal dan akhir rentang menangkap area yang tepat.
sumber
Sepertinya regex jahat Anda tidak cukup jahat ... :-)
Bagian Pencarian
Pencarian harus diubah menjadi ini:
Ini termasuk beberapa hal yang tidak biasa dan banyak tanda kurung ... Mari kita lihat apa yang kita miliki di sana:
The Caret (
^
)Tanda sisipan digunakan untuk berarti awal dari garis. Saya pikir kita sudah akrab dengan yang ini.
Poin penting,
^
tidak berfungsi kecuali sebagai karakter pertama dalam pola Anda. Setelah itu diambil kata demi kata. Untuk memasukkan awal baris dalam ekspresi Anda, Anda perlu menggunakan\_^
. Namun, dalam situasi kami, kami tidak membutuhkan itu.(Ada fenomena serupa dengan
$
dan\_$
)Tanda kurung pertama dan terakhir (
\( ... \)
)Tanda kurung pertama dan terakhir digunakan sendiri yang artinya akan mengambil apa pun yang muncul di dalamnya dan mengaturnya dalam parameter
\1
. Anda sudah menggunakannya di regex Anda sendiri, jadi saya akan menganggap Anda juga terbiasa dengan yang ini.Set kurung kedua
Seperti yang Anda perhatikan, ada tanda kurung kedua yang diikuti oleh tanda bintang
\( ... \)*
. Ini berarti kami mencari apa pun yang cocok dengan beberapa kali. Ini adalah cara biasa menggunakan tanda bintang sehingga Anda harus terbiasa dengannya.Set kurung ketiga, OR, dan
\_.
Ya, sebenarnya ada tiga tanda kurung sebelum kata
Show
. Set terakhir ini diperlukan karena dua alasan:\|
dan berikut ini@!
.Sehubungan dengan operasi ATAU, Anda harus sudah terbiasa dengannya.
Urutannya tidak penting di sini. Ini
\
diperlukan di depan|
untuk bekerja di vim.Tanda kurung di sekitar ungkapan ini memungkinkan kita untuk mengikuti ekspresi dengan sesuatu . Di sini
@!
.Yang ini kurang familiar. Artinya kalau tidak cocok . Penggunaan ini tidak mudah, tetapi Anda harus mengikuti ungkapan itu dengan apa yang ingin Anda ekstrak yang tidak cocok dengan ungkapan tersebut. Inilah mengapa kita memiliki di
\_.
balik pola itu.The
\_.
berarti cocok sesuatu apapun. Berlawanan dengan.
karakternya sendiri, yang tidak cocok dengan\n
karakternya. Dengan kata lain, kami mencocokkan karakter apa pun pada sejumlah baris kecuali jika cocokShow
atauHide
.Perhatikan bahwa tanda kurung di sekitar ungkapan itu juga penting seperti tanda bintang, jadi semua ini yang membuatnya bekerja:
alias mencocokkan berapa pun sampai ke yang berikutnya
Show
atauHide
karakter (catatan bahwa hal itu juga akan cocokShowing
,Shower
,HideMe
, dll Anda harus dapat menggunakan\<
dan\>
jika perlu untuk mencocokkan kata dengan tepat.)Catatan Samping: untuk mencari di banyak baris, juga dimungkinkan untuk menggunakan
\n
karakter dalam pola. Namun, itu tidak serbaguna daripada\_.
polanya.SetFontSize 28
Sekarang bagian ini juga harus disertakan
SetFontSize 28
. Sama seperti yang Anda miliki di regex Anda. Jika tidak ada yangSetFontSize 28
muncul di bagian itu, coba cari lagi di bagian selanjutnya.Karena negasi di atas (kecocokan kecuali
Show
atauHide
) pencarian tidak bocor ke bagian berikutnya, mengambil risiko mengacaukannya.Bagian Penggantian
Penggantinya sama seperti yang Anda miliki:
Kami menggunakan tanda kurung dalam Pencarian sehingga
\1
berfungsi seperti yang diharapkan.Cari dan Ganti Lengkap
Pola yang dihasilkan seperti ini:
The
\(Show\|Hide\)
harus mencakup semua kemungkinan header .Sumber
Regex untuk mencocokkan karakter apa pun termasuk baris baru (
\_.\{-}
)Cari baris yang tidak mengandung pola dan pencarian bermanfaat lainnya (
@!
)Dokumentasi Vim: pattern (
\_^
)sumber
()*
, versi saya jawaban Anda:%s/\v^Hide.*\n(\s+.*\n)*\s*SetFontSize\s+\zs28/16
.