$Id: enumre.html,v 1.7 1999/03/15 15:20:08 mas Exp $

enumre.rb

enumre.rbには ARegexp というクラス群が入っています。 以前は RE で始まる名前だったのですが改名しました。 ARegexp は 配列 ([], sizeメソッドを持つもの) に対してパターンマッチングを行ないます。
もっと適した名前はないでしょうか?

ARegexpとは

ARegexp は 配列 ([], sizeメソッドを持つもの) に対してパターンマッチングを行ないます。 たぶん、Regexp相当なものを記述できると思います。 まだコンパイラ (regcmp相当) 部分はありませんので、 直接 ARegexp を new や add でつないでパターンを作る必要があります。

次の例は ruby スクリプトから埋め込みドキュメントを抽出するパターンです。

reg_begin = ARegexpProc.new(proc{|v| v.index('=begin')==0})
reg_end = ARegexpProc.new(proc{|v| v.index('=end')==0})
reg_any = ARegexpAny.new.repeat(0, -1).greedy(false)

pattern = ARegexp.new([reg_begin, reg_any, reg_end])

実際に抽出するには次のようにします。

list = $<.read.to_a

pattern.scan(list) do 
  contents = pattern.matching_data[1]
  contents.each do |line|
    puts line
  end
  puts
end

このサンプルもダウンロードできます。


ARegexpのなかま

次のクラスが用意されています。

ARegexpAbstract
すべてのパターンの雛形で、 パターンの繰返しなどの機能が実現されてる。 以下のパターンで足りないときはこのクラスを拡張して新しいクラスを 作って下さい。
ARegexpProc
new(proc)で与えたブロックを評価して真となる値にマッチします
ARegexpEq --- 値の == による検査
new(value)で与えた値と == となる値にマッチします
ARegexpInclude --- 値の include? による検査
new(list)で与えたlist.include? が真となる値にマッチします
ARegexpSeq --- 並び
いくつかのARegexpの並びとマッチします
ARegexpAlt --- 選択
いくつかのARegexpの選択肢のうち一つでもマッチすればマッチします。
ARegexFirst, ARegexLast
先頭または末尾にマッチする
ARegexp
ARegexpのインスタンス階層の根となるもの。一番外側の式(?)。 ARegexpSeq と同様の機能があるが、繰返しなどは設定できない。 ARegexpは list に対して sub, gsub, scan などの操作ができる。

ARegexp はインスタンス階層の根となるオブジェクトです。 唯一、sub, gsub, scan などの操作、マッチした部分リストの取り出しができますが、 repeat, greedy などの指示はできません。


メソッド

共通のメソッド

repeat(m, n)
パターンの繰返しの指定。このパターンを m 回から n 回の繰り返す。 n が nil または -1 のとき、上限なしの指定となり何回でも繰り返す。 レシーバを返す。
greedy(yes=true)
yes が真のとき最短一致、偽のとき最長一致となる。 repeat と greedy を組み合わせると Regexp の *, *?, +, +?. {m,n}, {m,n}?が 表現できる。レシーバを返す。
match_one(list, index=0)
配列 list のオフセット index の要素から一回マッチさせたときの、 移動先のオフセットのリストを返す。 移動先がない (マッチしない) ときは空リスト [] を返す。 一般にARegexpAbstract の拡張するときはこれを override する。
match(list, index=0)
配列 list のオフセット index の要素から 繰返し回数も考慮してマッチさせたときの、 移動先のオフセットのリストを返す。 移動先がない (マッチしない) ときは空リスト [] を返す。

ARegexpのメソッド

new(list)
パターンの並びと順にマッチします。(ARegexpSeq と同じ)
repeat, greedy
使えません。
matching_data
マッチした部分リストのリストを返す。 リストは保持しているパターンの並び順に格納されている。 Regexp では () で指定した部分だけを取り出せるが、 ARegexp では直接保持しているすべてのパターンについて部分リストが 作成される。
matching_index
マッチした部分リストのoffsetのリストを返す。 リストは保持しているパターンの並び順に格納されている。
=~(list)
list中で最初にマッチするオフセットを返す
gsub(list) ブロック
list中でselfのパターンにマッチする部分ごとにブロックが評価され、 その戻り値のリストに置換される。
scan(list) ブロック
list中でselfのパターンにマッチする部分ごとにブロックが評価される。
sub(list) ブロック
list中でselfのパターンにマッチする最初の部分でブロックが評価され、 その戻り値のリストに置換される。

その他のクラス

もっとも単純なパターンである ARegexpProc とその派生クラス ARegexpEq, ARegexpIncludeのメソッド

ARegexpProc.new(ブロック)
ブロックが真となる値とマッチするパターンを作る
ARegexpProc.negate
偽となる値とマッチするようにする
ARegexpEq.new(obj)
ARegexpProc.new(proc{|v| v==obj}と等価
ARegexpInclude.new(list)
ARegexpProc.new(proc{|v| list.include?(v)}と等価

並びと選択

ARegexpSeq.new(list)
直列のパターンの生成。 パターンの並びを順にマッチさせすべてがマッチしたときに このパターンがマッチしたことになる。
ARegexpSeq.add(aregexp)
パターンの並びにパターンを追加する
ARegexpAlt.new(list)
選択パターンの生成。 パターンの群のうち、どれかがマッチしたときにこのパターンのマッチとなる。
ARegexpAlt.add(aregexp)
パターンを追加する

download


m_seki@mva.biglobe.ne.jp