emacsメモその3・elisp正規表現編

10000HITついでにアクセスログをながめてたら、「emacs redo」の検索で来てる人がやけに多い…
と思ったら「emacs redo」「emacs undo redo」でGoogleでもYahooでも1ページ目に表示されてるよΣ( ̄□ ̄;
うわわわわ。なんというSEO。そんなたいしたこと書いてなくてほんとすんません。

そんなわけで思い出したかのようにemacsメモ第3回です。
今回はちょっぴりマニアックに正規表現の話でも。
例によって興味ない人はスルー推奨&上級者のツッコミ歓迎ですよ!

※以下、"\" は半角バックスラッシュ(もしくは¥マーク)をあらわします。

EmacsLispの正規表現がややこしい理由

perlとかの正規表現に慣れている人から見ると、とにかくなんだかやたらとエスケープさせられる、というのが第一印象かと思います。っていうか私はそうでした。
具体的には、グループ化をあらわす "( .. )" や選択をあらわす "|" が、elispでは "\(.. \)" だの "\|"だのになります。
うん。それだけでも十分めんどいですね。
くわえて、elispの正規表現は文字列として記述され、関数に渡される前に一度評価されるというめんどくさい仕様があります。
たとえば

 (re-search-forward "\\\\")

と書くと、"\\\\" は一度評価されて "\\" となってから re-search-forward に渡されます。で、これは正規表現中では "\" をあらわしますよ、と。
そう、"\" を表現するのに "\\\\" って書かなきゃいけないんですよ。どんだけー。
同様に、"foo" または "bar" にマッチさせようと思うと、

 \\(foo\\|bar\\)

ですよ。なんのいやがらせですか。素直に "(foo|bar)" って書かせてくれよ…

re-builderべんり

正規表現書いてみたけどこれで正しいのかわかんねーよ!ってかこれ何にマッチするんだよ!
っていうときは M-x re-builder オススメ。
正規表現が文章中のどの部分にマッチするか教えてくれる。文法的にまちがった正規表現書いてたら忠告してくれる。べんり。

ちなみに

C-u C-s とかのコマンドで正規表現を入力するときは入力は評価されずそのまま関数(コマンド)に渡されるらしい。
すなわち、"foo" または "bar" なら

 \(foo\|bar\)

でよいと。
これ気づかないとハマります(ハマりました)。

というか普段正規表現使うのってほとんどはコマンドからだよね。
正規表現での置換(query-replace-regexp)(C-M-%)(←どうがんばっても片手では押せない)あたりは使いだすとやめられません。

なんだかんだいって使いこなせればかなり複雑なテキスト処理もできるので便利なんですよ(フォロー)

どうでもいいですが

"\(.. \)" っていうのがなんか顔文字っぽくて可愛い。「置いといて」みたいな。

参考

GNU Emacs Lispリファレンスマニュアル: 探索と一致


  • C-M-% 、頑張って片手で押してみました。でも ESC を使えば頑張る必要も無いですね。 – Riso (2008年09月27日 23時27分31秒)
  • あれ…Ctrl+Shift+5の時点できっつい私は人差し指が短いですかそうですか…。CtrlとShiftを小指でまとめ押しすればいけるか。 – B@管理人 (2008年09月28日 09時42分40秒)
  • 括弧系をエスケープするのって、昔ながらのUNIXの正規表現がそうなんだね。で、POSIXの拡張正規表現で要らなくなったらしいよ。(http://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE)それにしても、ロケールによって「[a-z] ではすべての小文字のアルファベットにマッチしない」っていうのはどうなんだ。この前のutf8フラグ以降のperlの\wの扱いもどうかと思ったけど。厳密に指定したければ[abcdefg….]って書けってか!? – りうの (2008年10月11日 23時53分39秒)
  • へぇへぇへぇ。sedとかでも旧式表現使うのか…。多言語対応はほんとにもうなんというか日本語圏に生まれたことを恨まざるをえない(-_-) – B@管理人 (2008年10月12日 09時09分39秒)