今日,BeautifulCodeを読み始めたんだけど,1章目から正規表現エンジンを実装していたりして,かなり刺激的な内容だった.残りの章を読み進めていくのが楽しみ.
- 作者: Brian Kernighan,Jon Bentley,まつもとゆきひろ,Andy Oram,Greg Wilson,久野禎子,久野靖
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/04/23
- メディア: 大型本
- 購入: 30人 クリック: 617回
- この商品を含むブログ (191件) を見る
この1章には,C言語で書かれた正規表現エンジンのコードが記載されている.この正規表現エンジンは,正規表現のうち
. ^ $ *
が使えるようなやつで,もともと,プログラミング書法に載っていたやつらしい.教育のために非常に簡潔できれいに書かれていて読みやすい.
そこで,せっかくなので,この正規表現エンジンをRubyに移植して理解を深めるなどしてみた.とりあえず,書いたコードをみたいひとはこちらへ.
なげえ
サンプルのCのコードをRubyに移植するに当たっていくつか気づいたことがあったので,以下はそのメモ.正規表現エンジン自体への考察はないので,それが読みたい人はスルーしてね.
Ruby ひく 正規表現
まず,Rubyはそもそも正規表現をそなえている言語なので,正規表現をつかわずにプログラムを書こうとすると,少し大変になる.
もとのCのコードはポインタをうまく使って,かなり簡潔なコードになっている.たとえば,ある文字が連続する部分を見つけて,その後ののこりの文字列を見つけるためのコード(ある文字がcならccccccxyzという文字列のxyzを見つける)は,サンプルでは以下のようになっている.cが連続する文字,textが対象の文字列としたとき,
for (t = text; *t != '\0' && (*t == c || c == '.'); t++)
;
となる.tがもとめる文字列を指している.
で,これをRubyで書き下すと,
start = 0
text.each_byte do |tc|
break if tc.chr != c && tc.chr != '.'
start += 1
end
t = text[start..-1]
という感じになって,Rubyにしてはもっさりした感じになってしまう.いや,さすがにもう少しましな書き方があるはずだよ,
/#{c}*(.*)/ =~ text
$1
たしかに,これくらい簡潔だとRubyらしい.Rubyできる子じゃん!って,これ正規表現つかってるよorz
さすがに,Rubyで正規表現を使わないことにすると,文字列処理が若干大変になってしまう.少なくとも,ぱっとみわかりにくいコードになってしまう.簡潔な記述が強みのLLにとっては正規表現はかなり重要なパートナーなのだぁ.
String#[]
さらに,細かいことで,Ruby1.8.6の文字列に添え字でアクセスすると,
>> "hello"[0]
=> 104
なんか,文字コードが帰ってくる.twitterで聞いてみたところ,わりと常識っぽくて,
>> "hello"[0].chr
=> "h"
>> "hello"[0..0]
=> "h"
などとするのが良いらしい.さすがにこの挙動はだめな感じがすると思っていたら,1.9ではちゃんとStringが返るとのこと.twitterで答えてくださったみなさま,ありがちょー!