emacsで正規表現による置換を快適に行いたい件

emacsで正規表現による置換を結構快適に使えるようになったので記録しておきます。

emacs標準コマンドのM-x replace-regexpは拡張正規表現と呼ばれる構文に対応していないので、スクリプト言語等で使用できる正規表現よりも機能が低く使いにくいのが問題でした。

結論を先に書きますと、以下手順でemacsから快適に正規表現による置換を行えるようになりました。

  1. .zshrcに[[ $EMACS = t ]と書いてemacsから使用するシェルをzshに設定し
  2. .zshenvにsetopt RC_QUOTESと書いて’のネストを許可し、
  3. M-!やM-|から実行したコマンドの履歴もシェルと共有して
  4. emacs上でC-u M-|からperl -nle ‘パターン;print’で置換

さて、始まりは前の職場の人のperlの正規表現は凄いという発言です。
その時はあまり興味が無かったのですが、HTML解析を最近頻繁にするようになると
綺麗にツリー構造が作れない場合が多く、仕方なしに正規表現を使わないといけなくなったのでどうせならという事で調べる事にしました。

少し調べてその人の発言内容は、先読み、後読みの事だと知りました。
そしてもう少し調べていくと、最近では先読み、後読みはperlでなくてもphp,python,ruby等でも使えるのですが、emacsのM-x replace-regexpでは使えないという事が解りました。

能力に違いのある複数の正規表現の使い方を覚えておく事に強い抵抗感があったので、emacsのM-x replace-regexpは使いたくありませんでした。かといってperlスクリプトを毎回書くのは面倒すぎて正規表現を使わなくなってしまいそうです。

しばらく悶々としていたのですが、perlにはnオプションというのが存在していて、l,eと組み合わせてperl -nle ‘スクリプト’と書くと以下と同等の処理を実行できる事を知りました。

while(<>) {
    chomp($_);
    スクリプト
}

これはかなり便利でemacs上からC-u M-|からのコマンド実行と組み合わせれば、
perlでの置換をreplace-regexpと同じ間隔で使用する事が出来ます。

しばらく気分よくこの状態で使っていたのですが、問題がまだありました。
それはM-!, M-|で実行したコマンドの履歴がemacsの再起動の度に消えてしまう事です。
慣れて正規表現を書くのは退屈な作業になってきてましたので、何度も同じ正規表現等書きたくありません。なんとか履歴を残したいということを思い、色々調べてみましたが、上手く見つからず行き詰まっていたのですが、はてな人力検索に質問してみたところ、ドンピシャの回答を頂きまして、晴れてシェルのヒストリと共有する事が出来るようになりました。(内容はリンク先を参照ください)

またzshのRC_QUOTESオプションを利用すると’で囲まれた文字列の中で”と書く事で
‘を表現する事が出来るようになります。M-! perl -nle ‘スクリプト’の形式で実行していると、
必然的にスクリプトが’で囲まれる形になるのでスクリプト中で’を使う事が出来ません。
しかしSQLへの置換時等、’を使う場面は多いので重宝します。この際に設定を行うファイルは
.zshrcではなく.zshenvである事に注意して下さい。

以上でemacsから気持ちよく正規表現による置換をする方法をまとめました。
もっといい方法があればぜひとも教えて下さい。

参考

  • 先読み、後読み

    正規表現

  • 正規表現パズル
    http://oraclesqlpuzzle.hp.infoseek.co.jp/regex/
  • 各環境で使える正規表現
    http://www.kt.rim.or.jp/~kbk/regex/regex.html

Leave a Reply

Your email address will not be published. Required fields are marked *