正規表現には色々な方言があり、微妙に食い違っていて困ります。とはいえ、「.」(ピリオド)、「*」(アスタリスク)、「+」(プラス)などの典型的なメタ文字はさすがに共通ですがね。
「または」、「どれか」を意味する「|」(縦棒)や、グルーピングの「(」と「)」(丸括弧)などもたいていの方言で使えます。が、Emacasの場合、縦棒や丸括弧は「\」でエスケープする仕様となっています。「『空白またはタブ』の1回以上の繰り返し出現」は、( |\t)+
ではなくて、\( \|\t\)+
です(([ \t]+
と書くこともできます。このほうが簡潔でいいですね。))。さらに悪いことには、Emacsにはスラッシュを使った正規表現リテラルがないので、正規表現を文字列として記述します。文字列リテラルにおける「\」のエスケープが重なり、次のようなことになります。
(setq re "\\( \\|\\t\\)+")
文字列sから、行頭の「空白またはタブ」の連続を取り除き「空白、タブ、ハイフン、コロン、セミコロン以外の文字の並び」を取り出すコードをJavaScriptとEmacs Lispで書いてみると次のようになります。
var re = /^( |\t)*([^- \t:;]*)/;
var s = " hello-world.";
re.test(s);
RegExp.$2;
(setq re "^\\( \\|\t\\)*\\([^- \t:;]*\\)")
(setq s " hello-world.")
(string-match re s)
(match-string 2 s)
Emacsの方式はいかにも見にくいですね。
もうひとつ小さな話題を。
.emacsの設定サンプルなどを見ていて「おやっ?」と思うことがあります。「.js」で終わる文字列のパターンが "\\.js$"
じゃなくて "\\.js\\'"
なんて書いてあることがあります。この「\'」(文字列内なら「\\'」)はEmacs特有のメタ表現で、http://www.bookshelf.jp/texi/elisp-manual-20-2.5-jp/elisp_34.html#SEC550 を引用すると:
- \` -- 空の文字列に一致するが、一致対象であるバッファや文字列の先頭に限る。
- \' -- 空の文字列に一致するが、一致対象であるバッファや文字列の末尾に限る。
ふーん、なるほど。