読者です 読者をやめる 読者になる 読者になる

検索 `/` で上手くいっても,エスケープはきちんと

またやってしまいました...
いろんな人に迷惑かけてしまいました.
上唇ハレてます orz

自戒の意を込めてw


The Night Before / johndal

閑話休題

あぁ、そういえばそう言うの前にもあったっけな、と思って残念な気分になったので今度はメモしておきたいと。

markdown でのリンクは "参照スタイル reference-style links" を好んで用いるのですが、こんな感じで。;

I get 10 times more traffic from [Google][1] than from
[Yahoo][2] or [MSN][3].

[1]: http://google.com/ "Google"
[2]: http://search.yahoo.com/ "Yahoo Search"
[3]: http://search.msn.com/ "MSN Search"

そんな記載をした行に対し一括検索を施したく作業していたら、「あぁーそーだったけな!」と。

ここでしたい話というのは

結論としては、検索置換時のパターンでのエスケープはきちんと
例え検索コマンドでは上手く行こうとも、だ。

今回の事例だと具体的には、
ブラケット "[]" を "文字列として" 扱いたい場合は、開き/閉じ共に \[\] ときちんとエスケープする、と言うこと。

至極もっともな話なのではあるのですが、ちょいとハマりました...

検索 '/' では上手くいくけど、置換 :s[ubstitute] だとエラー?

心配な置換をする時、まず検索コマンド / で探りを入れるような情弱ゆとり世代だったりするので、そんなのでアタリをつけてから :s コマンドの pattern に <C-r>/、と甘ったれたことをよくやります。

今回も検索コマンドで餌付け出来たのを見て、置換コマンドを実行したら、E486: パターンは見つかりませんでした: ... と。

エスケープ \ について、両者にあるちょっとした違い

markdown での参照スタイルは、ブラケット "[]" に番号を入れ... となります。
この記述をターゲットにしたいので、検索コマンドで入力しながら /^[\d\+\]:.* な感じでイメージ通りの結果を得ました*1

ですが、このパターンを置換にそのまま持っていくと上述エラーになるのです。

「?」と再び検索コマンドで試してみると...上手くいきます。
が、置換コマンドを実行するとエラー。

と、これを単細胞はバカのひとつ覚えの如く何度も行ったり来たりと繰り返すわけです orz

きちんとエスケープ

何が問題か、と言うのは冒頭でも述べました、エスケープ \

ご存じの通り "[]" は、そのまま記述すると "文字列として" ではなく、ブラケット内に記載したキャラクタの《どれかにマッチ》、というそれはコレクションと言うらしいのですが、として扱われます。

今回は違います。

ブラケットを "文字列として" 扱うには \[\] と開き/閉じ両方をエスケープしてやる必要があるわけで、それが不十分だと置換コマンドに怒られていた、となります。

仕様? だとしたら、どうしてなのでしょう。
置換は基本通りなのに検索はなぜ緩いのか、は良く分かっていません。

ちなみに <C-r>/ っては

こういうことです。

レジスタには 9 種類ある:
:
9. 最終検索パターン用レジスタ "/"

/レジスタには、直前に使った検索のパターンが格納されるとのこと。
それを呼び出している、とうことです。

詳細は :h registers:h quote/ を。

/ 叩いて検索し、思い通りの結果だったら、今度は : 叩いて置換コマンドを発行するわけです.
ということで,:s/ に続いてパターンを定義するわけですが、ここで C-r/control キー押しながら r キー押下し続いて / と入力、をします。
すると、先程検索で使ったパターンの内容が挿入されます。
あとはいつも通り、/ に続けて置換する文字を書き、フラグ等を指定する、といった塩梅です。

ちなみにパターンの履歴だして、編集することもできる

結構気に入っています。

それは /<C-f>
/コマンドラインに入り、そこで control キーと f を同時押下。

すると過去の検索パターンの履歴が出ます。

内容を編集できます。
編集し終わったら で確定。

直前、または過去に使用したパターンをそのまま、あるいは修正変更して再利用したい時などは便利だったりします。

例えば直前に使用したパターンをちょっと直したい、なんて言うケースでしたら、
/<C-f> で検索パターンの履歴を出し、
このリスト最終行が直前使ったパターンです。これを編集して

そうしてレジスタ / を呼び出すと、その編集したものが反映されたパターンが出てくると。*2

/ 叩いて入ったコマンドライン上で、矢印キー 押下しながら辿りそこで修正、と言うのもありでしょうが、想定した順に出てこない時があったり、可視性など考えると作業はより効率的かと思いますし、なによりいつもの hjkl やらのキーストロークで作業が出来るというのもメリットじゃないかと。

おしまい。

*1:ちなみに、'^[\d+]:' とエスケープ付けるのを逆、つまり前(開き)括弧側にのみつけても同じだったり。

*2:もちろんそのパターン文字列をヤンク 'y' してプット 'p'、というのでも良いですが。