以下の内容はhttps://hakobe932.hatenablog.com/entry/20080510/1210445882より取得しました。


BeutifulCodeの正規表現エンジンをRubyに移植

今日,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で答えてくださったみなさま,ありがちょー!

ソースコード

とりあえず,今日書いた正規表現エンジンをgitの練習もかねてgithubで公開してみた.

hakobe's practice-of-beautiful-code at master -- GitHub

最新の版では+が使えるようにしてあったり,ちょっとだけ改良してある.

他に,?を実装したり,処理をパターンのコンパイルとマッチングに分割するなど,改良するポイントはいろいろあるので,勉強ついでにちびちびコミットしていくかも.最終的には,PatternクラスとMatcherクラスを実装するとこまでいきたいなぁ.




以上の内容はhttps://hakobe932.hatenablog.com/entry/20080510/1210445882より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14