$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)
- パターンを追加する
m_seki@mva.biglobe.ne.jp