正規表現を使用して検索および置換


26

多くのユーザーのデフォルトが入ったファイルがあります。テキストの一部を変更したいのですが、マッチャーとリプレースメントの作成に苦労しています。次の例を使用します。

###############################################################################
# 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

私は交換したい# Trackpad: ...running "Trackpad: ..."

問題を分解して、正規表現テスターを使用して何かを思い付きました:

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

Vimでこれを使用しようとすると、うまくいきません。

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

私の問題は、具体的には次の2つの質問に要約されると思います。

  1. \n文字の検索を回避し、代わり#に検索グループの最後に表示されないようにするにはどうすればよいですか?
  2. キャプチャグループを効果的に使用するにはどうすればよいですか?

以下にいくつかの素晴らしい答えがあります。3つすべてから選択するのは難しいですが、選択した答えが私の元の仕様にとって最も正確であると感じています。実際のファイルで 3つの回答すべてを試して、それらについてどのように感じているかを確認することをお勧めします。

回答:


18

ただ明確にするために…これが置換の結果であるようにあなたが頼んだと思いますか?

###############################################################################
# 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

その場合、次のコマンドをお勧めします。

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

パターンの説明

:s/PATTERN/REPLACEMENT/ある代替コマンドが。パーセントサインイン:%sは、現在の行だけでなく、ファイル全体で機能するようにします。

対象\n\n行は空白行の後になければならないという。前の空白行を気にしなければ、^それで十分でしょう。

#\s\+ハッシュ文字とそれに続く1つ以上の空白文字に一致します。 \(.*\)行の後続のすべてのテキストをキャプチャします。

置換テキストの説明

^M^M\n\nパターンに存在していたものを置き換えるために、行の両端を挿入します。そうしないと、テキストは空白行の前の行の末尾に移動します。それぞれを入力するには^M、を押しCtrl-V Ctrl-Mます。

次に、文字列を挿入し、その後にrunning二重引用符で囲まれた括弧でキャプチャされたものを挿入します。


あなたの答えを編集することはできませんが、あなたが意図したものだと思います:%s/\v\n\n#\s+(.*)/^M^Mrunning "\1"/(「魔法の」フラグを追加しました)。私の元の質問に対して正しい答えを選ぶのは本当に難しいですが、この答えは私の最初の予想された答えに最も近いと思います。また、範囲を選択する必要なく、ファイル全体で機能する唯一のものです。
squarefrog

1
新しい行を取得する\r代わりにIIRCを使用できます^Mか?
ムル

11

私は次のようなものを使用します:

:s/^#\s\+\(.\{-}\):/running "\1":/
  • ^##行の先頭に固定された文字と一致させるため(これは質問1に答えます)
  • \s\+ 空白を1回以上一致させる
  • \( グループを開始するには(これは質問2に答えます)
  • .\{-}\貪欲でない方法で任意の文字を0回以上一致させる。これは.*、可能な限り一致しないようにし、可能な限り一致させないという点で異なります。:コメントに文字を追加して、これが重要な理由を確認してください
  • \) サブグループを終了します。
  • : リテラルに一致 :

次に、これを必要なテキストに置き換え、\1キャプチャしたグループを参照するために使用します。

正規表現テスターを使用して何かを思いついた

正規表現の構文はWikiの構文に少し似ています:それらの束があり、それらはすべて一見して同じように見えますが、明らかに他のものより優れているものはありませんが、多くの違いがあります。

今日、いわゆる「Perl互換」正規表現はほとんどの言語で事実上のデフォルトですが、Vim正規表現はPerl互換表現と互換性がありません!Vimの正規表現構文は、Perlが存在しなかった少なくとも70年代にまで遡ります。

あなたが使用する必要がありますサブグループ、でこれを見ることができ\(ない((ただし、より一般的なPOSIX「拡張」構文やPerlの構文で、これはPOSIX「基本」構文と互換性があります)。\vパターンにフラグを追加することでこれを制御できます(詳細:help /\vを参照)。これにより、「互換性が向上」しますが、完全ではありません(.{-}たとえば、貪欲でない一致に使用する必要があります)

したがって、これは、「正規表現テスター」を使用することが、ほとんどではなく、ほとんど機能する理由を説明するかもしれません。

Vim正規表現の概要/チートシートとしてhttp://www.vimregex.com/


1
特になぜregex!= regexであるかについてのすばらしい答え。検索と置換については、コメントにが付いている場合と付いていない場合があるため、少し注意が必要:です。詳細については、完全なファイルを参照してくださいgithub.com/squarefrog/dotfiles/blob/master/osx/...
squarefrog

8

あなたはできる:

  • で終わらない行を検索#:/[^#]$/
  • #\s(.*)行の先頭で置き換えます:s/\v^#\s(.*)/running "\1"/

グループを使用するには、次のいずれかが必要です。

  • 括弧をエスケープして、正規表現構文の一部になるようにします:\(.*\)または
  • 使用「魔法」と表現を開始することにより\vs/\v...

それを組み合わせる:

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

1
これは見事に機能します。私が書くのに必要なテキストだけでなく、タグの意味の説明を含めてくれてありがとう。
squarefrog

正規表現構文の一部になるために、括弧をエスケープする必要があることを明確にしてくれてありがとう。正規表現グループを機能させるには常に問題がありました。
アダマ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.