Normal ifadeleri kullanarak bulun ve değiştirin


26

İçinde bir sürü kullanıcı varsayılanı olan bir dosyam var. Metnin bir kısmını değiştirmek istiyorum, ancak bir eşleştirici ve tekrarlayıcı ile gelmekte zorlanıyorum. Aşağıdaki örneği kullanarak:

###############################################################################
# Trackpad, mouse, keyboard, Bluetooth accessories, and input                 #
###############################################################################

# Trackpad: enable tap to click for this user and for the login screen
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true

Ben değiştirmek istiyorum # Trackpad: ...ilerunning "Trackpad: ..."

Sorunu yıkmak, bir regex test cihazı kullanarak bir şey buldum:

/\n\n#\s(.*)/g

Bunu Vim'de kullanmaya çalışırsam, benim için işe yaramaz:

:/\n\n#\s(.*)/running "\1"/g

Sanırım sorunum iki özel soruya yol açıyor:

  1. \nKarakter aramaktan nasıl kaçınabilirim ve bunun yerine #arama grubunun sonunda görünmediğinden emin olabilir miyim ?
  2. Yakalama gruplarını etkili bir şekilde nasıl kullanabilirim?

Aşağıda harika cevaplar var. Üçü arasında seçim yapmak zor, ancak seçilen cevabın asıl şartlarım için en doğru olduğunu düşünüyorum. Onlarla ilgili nasıl hissettiğinizi görmek için asıl dosyayla her üç yanıtı da denemenizi öneririz .

Yanıtlar:


18

Sadece açık olmak gerekirse ... Bunun yerine koymanın sonucu olmasını istediğine inanıyorum?

###############################################################################
# Trackpad, mouse, keyboard, Bluetooth accessories, and input                 #
###############################################################################

running "Trackpad: enable tap to click for this user and for the login screen"
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true

Bu durumda, aşağıdaki komutu öneriyorum:

:%s/\n\n#\s\+\(.*\)/^M^Mrunning "\1"/

Desenin açıklaması

:s/PATTERN/REPLACEMENT/bir yedek komutu. Oturum açma yüzdesi :%s, yalnızca geçerli satır yerine tüm dosya üzerinde çalışmasını sağlar.

\n\nİlgi çizgi boş satırdan sonra meydana getirmesi gerektiğini söyledi. Bir önceki boş çizgiyi umursamıyorsanız, o ^zaman yeterli olacaktır.

#\s\+bir veya daha fazla beyaz boşluk karakteri tarafından takip edilen bir karma karakteriyle eşleşir. \(.*\)satırdaki sonraki tüm metni yakalar.

Yedek metnin açıklaması

^M^M\n\ndesende bulunanları değiştirmek için iki çizgi ucunu yerleştirir . Aksi takdirde, metin boş satırdan önceki satırın sonuna taşınır. Her birini yazmak için ^M, tuşuna basın Ctrl-V Ctrl-M.

Sonra, ipi running, ardından çift tırnak içinde parantez içinde neyin yakalandığını izleyin.


Cevabınızı düzenleyemiyorum ama kastettiğine inanıyorum :%s/\v\n\n#\s+(.*)/^M^Mrunning "\1"/("sihirli" bayrağını ekledi). Asıl sorum için doğru bir cevap seçmek gerçekten zor, ama bu cevabın asıl beklenen cevaba en yakın olduğunu düşünüyorum. Ayrıca, tüm dosya boyunca bir aralık seçmeye gerek kalmadan çalışan tek dosyadır.
squarefrog

1
IIRC \ryerine ^Myeni hatlar almak için kullanabilirsiniz ?
muru

11

Gibi bir şey kullanırım:

:s/^#\s\+\(.\{-}\):/running "\1":/
  • ^##Satırın başında tutturulmuş karakterle eşleşmek için (bu, 1. soruyu cevaplar)
  • \s\+ Herhangi bir boşlukla bir veya daha fazla kez eşleştirmek için
  • \( grup başlatmak için (bu, 2. soruyu cevaplar)
  • .\{-}\herhangi bir karakteri 0 veya daha fazla kez açgözlü olmayan bir şekilde eşleştirmek ; bu, .*mümkün olduğu kadar az değil, mümkün olduğunca az eşleşmeye çalıştığından farklıdır . Bunun :neden önemli olduğunu görmek için yoruma bir karakter eklemeyi deneyin
  • \) alt grubu sonlandırmak için.
  • : değişmez eşleşir :

Daha sonra bunu istediğiniz metinle değiştiririz ve \1yakaladığımız gruba başvurmak için kullanırız .

Bir regex test cihazı kullanarak bir şey buldum

Düzenli ifade sözdizimi wiki sözdizimine biraz benziyor: birçoğu var, hepsi bir bakışta birbirine benziyor, hiçbiri açıkça diğerlerinden daha iyi değil, ancak çok fazla fark var.

Bugün "Perl uyumlu" normal ifadeler çoğu dilde fiili varsayılandır, ancak Vim normal ifadeler Perl uyumlu ifadelerle uyumlu değildir ! Vim regexp sözdizimi, Perl etrafta olmadığı zaman en azından 70'lere geri döner.

Sen kullanımına sahip alt gruplara sahip bu görebilirsiniz \(ve ((ancak daha yaygın POSIX'deki 'genişletilmiş' sözdizimi veya Perl sözdizimi ile bu POSIX 'temel' sözdizimi ile uyumludur). \vBayrağı bir desene ekleyerek bunu kontrol edebilirsiniz (Ayrıntılar :help /\viçin bakınız), bu onu "daha uyumlu" hale getirecek, ancak tamamen değil ( .{-}Örneğin, açgözlü olmayan eşleşmelerde kullanmak zorundasınız )

Bu yüzden "regex test cihazı" kullanmanın neden neredeyse ama tam olarak işe yaramadığını açıklayabilir.

http://www.vimregex.com/ , Vim regexps’in iyi bir genel bakışı / kopya kağıdı olarak.


1
Büyük cevap, özellikle neden regex! = Regex. Arama ve değiştirme için gelince, yorum bir olabilir ya da olmayabilir gibi biraz zor :. Detaylar için tam dosyaya bakın github.com/squarefrog/dotfiles/blob/master/osx/…
squarefrog

8

Yapabilirsin:

  • sonu gelmeyen satırları ara #::/[^#]$/
  • #\s(.*)Satırın başında değiştirin :s/\v^#\s(.*)/running "\1"/

Grupları kullanmak için şunlardan birini yapmanız gerekir:

  • köşeli ayraçlardan çıkın, böylece regex sözdiziminin bir parçası olabilirler: \(.*\)veya
  • ifadeyi şu şekilde başlatarak "magic" kullanın \v:s/\v...

Birleştirerek:

:/[^#]$/s/\v^#\s(.*)/running "\1"/

1
Bu mükemmel çalışır, sadece yazmam gereken metin yerine etiketlerin ne anlama geldiğinin bir açıklamasını eklediğiniz için teşekkür ederiz.
squarefrog

Regex sözdiziminin bir parçası olmak için parantezlerin çıkarılması gerektiğini açıkça belirttiğiniz için teşekkür ederiz. Her zaman regex gruplarıyla çalışmalarını sağlama konusunda bir sorunum vardı.
Adama
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.