Bagaimana saya bisa membuat pasangan saya tidak serakah di vim?

480

Saya memiliki file HTML besar yang memiliki banyak markup yang terlihat seperti ini:

<p class="MsoNormal" style="margin: 0in 0in 0pt;">
  <span style="font-size: small; font-family: Times New Roman;">stuff here</span>
</p>

Saya mencoba melakukan pencarian-dan-ganti Vim untuk menyingkirkan semuanya class=""dan style=""tetapi saya mengalami kesulitan membuat pertandingan tidak sesuai.

Upaya pertama saya adalah ini

%s/style=".*?"//g

tapi Vim sepertinya tidak suka ?. Sayangnya melepas ?membuat pertandingan terlalu serakah.

Bagaimana saya bisa membuat pertandingan saya tidak sesuai?

Mark Biek
sumber
Saya pikir jawaban Paul baik. Hanya mengatakan itu "?" tidak berarti opsional dalam vim (jika ini yang ingin Anda capai menggunakan "?")
LB40
15
@ LB, dalam banyak bahasa,. *? berarti cocok dengan karakter apa pun tetapi bersikap tidak serakah. Itulah yang dia coba capai.
Randy Morris
Terkait: Bagaimana membuat pencocokan regex menjadi tidak serakah? pada Vim SE.
Big McLargeHuge

Jawaban:

734

Alih-alih .*digunakan .\{-}.

%s/style=".\{-}"//g

Juga lihat :help non-greedy

Randy Morris
sumber
38
Tidak terlalu intuitif, apakah ini sesuatu yang hanya dilakukan vim?
Ehtesh Choudhury
95
Semuanya memiliki bahasa ekspresi regulernya sendiri ... itu salah satu masalah terbesar dengan regex.
Patrick Farrell
35
Banyak alat ini matang sekitar waktu yang sama dan secara mandiri mengembangkan dialek mereka sendiri dari bahasa ekspresi reguler. Banyak dari alat-alat ini juga sedang mencoba untuk memecahkan masalah yang berbeda sehingga masuk akal bahwa sintaksisnya bisa-berpotensi sangat berbeda di seluruh implementasi ini. Kita harus menerima bahwa inilah cara dunia nyata bekerja meskipun terkadang membuat hidup kita lebih sulit sebagai pengembang. Untungnya banyak alat setidaknya menyediakan implementasi regex yang kompatibel dengan Perl akhir-akhir ini. Sayangnya Vim bukan salah satunya.
Randy Morris
15
Jika ada orang seperti saya yang default pencarian mereka ke \v(bendera sangat ajaib) Anda akan ingin menggunakan .{-}.
jgillman
48
@Shurane @Ziggy Mnemonic: mengontrol jumlah pengulangan seperti {1,3}halnya (kawat gigi). Tanda minus -berarti: ulangi sesedikit mungkin (sedikit == minus);)
Ciro Santilli 郝海东 冠状 病 六四 六四 事件 法轮功
58

Pencarian tidak serakah di vim dilakukan menggunakan operator {-}. Seperti ini:

%s/style=".\{-}"//g

coba saja:

:help non-greedy
Vilhelm Gray
sumber
48

ada apa dengan

%s/style="[^"]*"//g
Paul Tomblin
sumber
7
Meskipun, untuk keuntungan saya sendiri, saya masih ingin lebih memahami hal yang tidak menyenangkan.
Mark Biek
17

Jika Anda lebih nyaman sintaks PCRE regex, yang

  1. mendukung operator yang tidak tamak?, seperti yang Anda tanyakan dalam OP; dan
  2. tidak memerlukan operator pengelompokan mundur dan kardinalitas (persyaratan sintaksis vim yang benar-benar berlawanan karena Anda tidak mencocokkan karakter literal tetapi menentukan operator); dan
  3. Anda telah [g] vim dikompilasi dengan fitur perl, tes menggunakan

    : ver dan periksa fitur; jika + perl ada di sana Anda bisa pergi)

coba cari / ganti menggunakan

:perldo s///

Contoh. Tukar atribut src dan alt di tag img:

<p class="logo"><a href="/"><img src="/caminoglobal_en/includes/themes/camino/images/header_logo.png" alt=""></a></p>

:perldo s/(src=".*?")\s+(alt=".*?")/$2 $1/

<p class="logo"><a href="/"><img alt="" src="/caminoglobal_en/includes/themes/camino/images/header_logo.png"></a></p>
FrDarryl
sumber
1
perldoberfungsi dengan baik, tetapi sayangnya tidak menyorot tes yang dipilih saat mengetik regex.
mljrg
12

Saya telah menemukan bahwa solusi yang baik untuk jenis pertanyaan ini adalah:

:%! sed ...

(atau perl jika Anda suka). TKI, alih-alih mempelajari keanehan regex vim, gunakan alat yang sudah Anda ketahui. Menggunakan perl akan membuat? pekerjaan modifier untuk tidak mencocokkan pertandingan.

William Pursell
sumber
2
Poin bagus, tetapi bisa dilakukan /patternuntuk memeriksa apakah Anda mencocokkan pola dengan benar sebelum menerapkannya dan menggunakan cpengubah dalam vim ekspresi reguler Anda juga bagus :)
João Portela
ini benar. semua solusi di sini tidak mendekati non-serakah! jika Anda harus mencocokkan [0-9] \ {7} dalam satu baris dengan banyak teks dan beberapa kemunculan pola itu, tidak ada solusi di sini yang akan dilakukan. Solusi di sini hanya bekerja untuk hal-hal sederhana (yang harus adil, adalah apa yang ditanyakan). tetapi jika Anda melakukan sedikit lebih dari pencarian sampai kutipan berikutnya, vim tidak akan membantu.
gcb
4

Dengan \v(seperti yang disarankan dalam beberapa komentar)

:%s/\v(style|class)\=".{-}"//g
Joao
sumber
2

Plugin eregex.vim menangani operator non-serakah *?dan+?

bain
sumber
@xsilenT github.com/othree/eregex.vim : "Disarankan untuk menginstal skrip menggunakan Vundle atau patogen."
eXe
maaf untuk itu saya tidak tahu cara menggunakan Vundle atau patogen.
xsilen T
-4

Hari,

Pemrosesan regexp Vim tidak terlalu brilian. Saya telah menemukan bahwa sintaks regexp untuk sed adalah tentang kecocokan yang tepat untuk kemampuan vim.

Saya biasanya mengatur sorot pencarian pada (: set hlsearch) dan kemudian bermain dengan regexp setelah memasukkan garis miring untuk masuk ke mode pencarian.

Sunting: Mark, trik itu untuk meminimalkan kecocokan serakah juga tercakup dalam buku bagus Dale Dougherty "Sed & Awk" ( tautan Amazon yang disanitasi ).

Bab Tiga "Memahami Sintaks Ekspresi Reguler" adalah intro yang sangat baik untuk kemampuan regexp lebih primitif yang terlibat dengan sed dan awk. Hanya bacaan singkat dan sangat dianjurkan.

HTH

Bersulang,

Rob Wells
sumber
7
Pemrosesan regex Vim sebenarnya cukup bagus. Ia dapat melakukan hal-hal yang tidak dapat dilakukan, seperti mencocokkan nomor baris / kolom atau mencocokkan berdasarkan klasifikasi karakter per-bahasa sebagai kata kunci atau pengidentifikasi atau spasi putih. Ini juga memiliki pernyataan lebar nol dan kemampuan untuk menempatkan ekspresi di sisi kanan pengganti. Jika Anda menggunakannya \vsangat membantu membersihkan sintaks.
Brian Carper
1
@ Brian, tepuk tangan. Saya akan melakukan regex bantuan dan melihat apa yang telah saya lewatkan.
Rob Wells
@RobWells, Sed & Awk , yang memang merupakan buku imho yang sangat baik, tidak secara eksplisit menghabiskan kata-kata pada penjumlahan rakus / malas. Sebagai buktinya, sama sekali tidak ada kemunculan kata-kata keserakahan atau serakah di dalam buku, dan hanya ada satu, tetapi tidak terkait, kemunculan kata malas .
Enrico Maria De Angelis
@ EnricoMariaDeAngelis itu tetapi contohnya tidak merujuk ke istilah secara eksplisit. Ini tentang bagaimana menyesuaikan regex Anda untuk menggunakan operator "tidak" untuk mencapai pertandingan yang tidak serakah. Istilah serakah dan malas tiba dengan mesin NFA Perl ketika mereka memperkenalkan operator untuk secara khusus mengubah perilaku pertandingan serakah.
Rob Wells