Emacs の正規表現の置換・検索 ( RegExp replace or search ) を賢くかわいくしてあげよう
いや、私が使いこなせないんじゃない! Emacs が悪いんだ!!
……と思ったので改造です。
頭おかしい! Emacs の正規表現
Emacs の正規表現は独特すぎて頭おかしいです。他のに慣れてると全然使いこなせません。
RegExp replace (正規表現での置換)のときも、
どの文字が正規表現に引っかかっているかわからず結果、
Replaced 0 occurrences
の一文を見てガッカリすることになります。
Emacs 標準搭載の Re-Builder という機能を使って、正規表現が一致するか見ることは出来ますが・・・*1
ちょっと例を見てみましょう。
使えない Re-Builder
<p name="lemon"> lemon </p> <p name="melon"> melon </p>
これの name="" の中身をそれぞれ fruits-lemon, fruits-melon に置換したいと考えてみましょう。
で、M-x re-builder
で Re-Builder を立ち上げて、
出てきた下の *RE-Builder* ボックスに入力して確認しましょう。
なるほど、emacs では \"\\([a-z]+on\\)\"
と入力すればいいんだな。
ずいぶんバックスラッシュ多いんだな、と理解してこれで replace してみようとしてみます。
しかし現実は非情!!
そこには Replaced 0 occurrences の文字が!!
「Re-Builderくんの嘘つき!!」
と純真な少女っぽい言葉も叫びたくなります。
ちなみに正しくは、 "\([a-z]+on\)"
⇒ "fruits-\1"
で置換できます。
わりとふつうです。
めんどくさいし引っかかりポイントな改行コード
正規表現の改行コードといえば、当然、バックスラッシュn、\n
です。
Emacs はそうではありません。C-q C-j
です。頭おかしいです。
ってか、私は C-TAB は next buffer への移動、C-q は previous buffer への移動にキーバインドしてるので、
C-q 押したとたんに違うバッファー(タブ)に飛ばされちゃうので使えません!!
You can enter a newline character using
‘C-o’
,‘C-q C-j’
, or‘C-q 012 RET’
.
と書かれていますが、私の環境では C-o でダメでした。(なんかキーバインド振ってたっけ)
解決策1 : foreign-regexp を使おう
詳しくはこちらを : Emacs: re-builder + foreign-regexp.elでたのしい正規表現 | 葉月夜堂
ただし、そこでも書かれていますが、
Emacs のバージョンが 24.4 や 24.5 では
Wrong type argument: commandp, ad-Orig-foreign-regexp/query-replace
とエラーが出て使えません。
私のEmacsは最新の 24.5 にしてあるので同じエラーが出て使えませんでした。
Perl, Ruby, Python, JavaScript といったいろんな言語の正規表現形式に対応していて、良さそうだったんですけどね。
別な方法を考えましょう。
解決策2(本命) : visual-regexp-steroids を使おう
参考 : visual-regexp-steroids.el : 【正規表現革命】isearchや置換でPerl/Pythonの正規表現を使おうぜ!
導入が少し特殊なので気をつけましょう。
まず visual-regexp-steroids のパッケージをインストールします。
このとき、 visual-regexp のパッケージもインストールされると思いますが、
そちらも大事ですので、emacs のプラグインを置いているフォルダにどちらも置いてください。
それから、pcre2el というパッケージもインストールしておくとよいでしょう。
これは、Python がインストールされていない(PATHが通ってない)パソコンで visual-regexp を使いたいときに必要になります。
私は複数パソコンでEmacsの設定を使いまわしているので、いちおう pcre2el はインストールしておきました。
さて、プラグインをEmacsが読み取るフォルダーに置きましたら、
init.el (Emacsの設定ファイル)に以下のように書き足します。
(defvar emacs-root (eval-when-compile '( (require 'visual-regexp-steroids) ))) ;; 上記のように書かないと、コンパイル時に `regexp-string' 由来の警告を吐く (setq vr/engine 'python) ; 'python, 'pcre2el, or 'emacs ;; python が インストールされてない環境では、上1行をコメントアウト、下2行をコメント解除 ;; (setq vr/engine 'pcre2el) ;; (require 'pcre2el) ;; multiple-cursors ( https://github.com/magnars/multiple-cursors.el ) を使っている場合は下1行をコメント解除 ; (global-set-key (kbd "C-c m") 'vr/mc-mark) ;; 普段の 'query-replace-regexp を visual-regexp に (define-key global-map (kbd "C-x C-r") 'vr/query-replace)
ふだんは (require 'visual-regexp-steroids) だけでプラグインを読み込むと思いますが、
~/.emacs.d/elpa/visual-regexp-steroids/visual-regexp-steroids.elc:Warning: reference to free variable `regexp-string' ~/.emacs.d/elpa/visual-regexp-steroids/visual-regexp-steroids.elc:Warning: reference to free variable `replace-string'
と Warning を吐いてうっとおしいので、上のように記述しておくことをオススメします。
*追記(2015/9/12 22:00):上記のように書いたのですが、これを記述するとそもそも visual-regexp が動かなくなることに気付いたのでやめてください。
ふつうに (require 'visual-regexp-steroids)
で呼んでください。
起動のたびに *Compile-Log* のバッファが開いてちょっと嫌ですが、あきらめるしかないですかね。
visual-regexp-steroids を導入するとこうなる!
複数行の置換が簡単にできる
例えばこのように、
<p name="lemon" > lemon </p>
" と > が別の行に行ってしまってるので連結したい、としましょう。
そのときはウィンドウ下に出ているように、C-c m
を押すと複数行検索になりますし、*2
ちゃんと \n
も使えますので簡単に置換することができます。
ね! かんたんでしょ!
Emacs の正規表現の融通きかなさに困ってる人、ぜひ visual-regexp-steroids を使いましょう。
これ無しの正規表現置換はしたくなくなりますよ!
ちなみに
私は正規表現を置換でしか使わないのでやっていませんが、
search でもこれを使いたい場合は、
(global-set-key (kbd "C-S-s") 'vr/isearch-forward) ;; Ctrl + Shift + s で前方検索 (global-set-key (kbd "C-S-r") 'vr/isearch-backward) ;; Ctrl + Shift + r で後方検索 ;; キーバインドはお好みで……
などと書いておけば OK です。
*1:Re-Builderについて : Emacs で正規表現を使うなら re-builder を使おう - higepon blog
*2:もしこのようにたくさんのメニューが出ていないときは、M-x vr/select-query-replace ののちに python と入力すると直るかと思います