- regex-tool 20170104.1118(in MELPA)
- A regular expression evaluation tool for programmers
概要
あなたは
- 正規表現を組み立てるのに苦労していませんか?
- マッチさせようと思った正規表現がうまく動かなくて困っていませんか?
- 正規表現のグルーピングは使いこなせていませんか?
それならば、
ここで紹介する
regex-tool.el
を
おすすめします。
作者は20年以上
Emacs開発に携わっている
現Emacsメンテナの
John Wiegley氏です。
標準の M-x re-builder
と
コンセプトは似ていますが、
こちらはターゲットとなる
文字列を指定して、
正規表現を組み立てる点が
違います。
M-x regex-tool
を起動すると、
- 新たなフレームが現れ
- 上中下のウィンドウに分割される
- 上→ *Regex*バッファ(正規表現を書くバッファ)
- 中→ *Text*バッファ(ターゲットとなる文字列のバッファ)
- 下→ *Groups*バッファ(マッチ箇所を表示するバッファ)
- 上→ *Regex*バッファ(正規表現を書くバッファ)
- *Regex*と*Text*を自由に編集すると
- *Regex*を書き換えると*Text*と*Groups*がリアルタイムに更新される
C-c C-k
で終了
のような流れで正規表現を組み立てます。
本設定では方言に合わせて
M-x regex-tool-emacs
- Emacs正規表現
M-x regex-tool-perl
- Perl正規表現
M-x regex-tool-ruby
- Ruby正規表現
で起動できるようにしています。
Fig1: M-x regex-tool-ruby
なお、
ソースコードは
平易に書かれているため、
Emacs Lisp中級者ならば
解読に挑戦してみましょう。
インストール
パッケージシステムを初めて使う人は
以下の設定を ~/.emacs.d/init.el の
先頭に加えてください。
(package-initialize) (setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/") ("melpa" . "http://melpa.org/packages/") ("org" . "http://orgmode.org/elpa/")))
初めてregex-toolを使う方は
以下のコマンドを実行します。
M-x package-install regex-tool
アップグレードする方は、
以下のコマンドでアップグレードしてください。
そのためにはpackage-utilsパッケージが必要です。
M-x package-install package-utils (初めてアップグレードする場合のみ) M-x package-utils-upgrade-by-name regex-tool
Perlにも対応
regex-tool.el
は
Emacsの正規表現だけでなく
Perlにも対応しています。
正規表現の情報を
表示するスクリプトは
regex-tool.el
に内蔵されているため、
Perlインタプリタがあれば動作します。
カスタマイズ変数
regex-tool-backend
で
emacs/perlを切り替えられますが、
本設定では
コマンドを定義して
両方とも使えるようにしておきます。
regex-tool.el
が
Perl対応になっているのは、
regex-render-perl
関数が
正規表現と文字列を受け取って
S式を返す関数になっているからです。
(defun regex-render-perl (regex sample) (with-temp-buffer (insert (format "@lines = <DATA>; $line = join(\"\", @lines); print \"(\"; while ($line =~ m/%s/mg) { print \"(\", length($`), \" \", length($&), \" \"; for $i (1 .. 20) { if ($$i) { my $group = $$i; $group =~ s/([\\\\\"])/\\\\\\1/g; print \"(\", $i, \" . \\\"\", $group, \"\\\") \"; } } print \")\"; } print \")\"; __DATA__ %s" regex sample)) (call-process-region (point-min) (point-max) "perl" t t) (goto-char (point-min)) (read (current-buffer))))
評価させると、
こんな感じになります。
$ (regex-render-perl "perl" "I love perl.") ((7 4)) $ (regex-render-perl "p(e)(r)l" "I love perl.") ((7 4 (1 . "e") (2 . "r"))) $ (regex-render-perl "(.)a" "I love papa and mama.") ((7 2 (1 . "p")) (9 2 (1 . "p")) (11 2 (1 . " ")) (16 2 (1 . "m")) (18 2 (1 . "m")))
文字列全体に対して何度もマッチさせ、それぞれ
- マッチ開始オフセット
- マッチ部分の長さ
- 部分文字列をインデックスつきのコンスセルのリスト
を返していることがわかります。
Rubyにも対応させてみる
それならば、
Rubyでも同様のことをすれば
Rubyの正規表現(Onigmo)にも
対応できます。
Rubyの正規表現を使いたければ、
regex-render-ruby
を定義しregex-render-perl
に:override
アドバイスをかける
の手順でできます。
上記の情報を使えば、
他言語にも対応できます。
設定 170110054733.regex-tool.el(以下のコードと同一)
(defun regex-render-ruby (regex sample) (with-temp-buffer (insert (format " line = DATA.read re = /%s/ print '(' pos = 0 while md=re.match(line,pos) printf '(%%d %%d', md.begin(0), md.end(0)-md.begin(0) puts md.captures.each_with_index{|c,i| printf '(%%d . %%s)', i+1,c.inspect } pos = md.end(0) puts ')' end print ')' __END__ %s" regex sample)) (insert (format "")) (call-process-region (point-min) (point-max) "ruby" t t) (goto-char (point-min)) (read (current-buffer)))) (defun regex-tool-emacs () (interactive) (setq regex-tool-backend 'emacs) (regex-tool)) (defun regex-tool-perl () (interactive) (setq regex-tool-backend 'perl) (advice-remove 'regex-render-perl 'regex-render-ruby) (regex-tool)) (defun regex-tool-ruby () (interactive) (setq regex-tool-backend 'perl) (advice-add 'regex-render-perl :override 'regex-render-ruby) (regex-tool))
実行方法
$ wget http://rubikitch.com/f/170110054733.regex-tool.el $ emacs -Q -f package-initialize -l 170110054733.regex-tool.el
本日もお読みいただき、ありがとうございました。参考になれば嬉しいです。