Hatena::Grouprubyist

たばさの RSSフィード

11/13(火) 2007

easy regexp

easy regexp - たばさの を含むブックマーク はてなブックマーク - easy regexp - たばさの

http://golf.shinh.org/p.rb?easy+regexp

ほかのソース見た。わからないので、ちから技で。

再帰するなら作り直さないといけない程度の、手抜き。というか再帰は苦手。

# easyregex.rb
li=gets
ans=[]

def Or a
 ans=[]
 ans<<a.split("|")
 ans
end

def hate a
 ans=[""]
 if a.class==String
  ans <<a
 else
  a.each{|i|
   ans<<i
  }
 end
 ans
end

def chars a
 dat=[]
 a.each_byte{|i|
  dat<<i.chr
 }
 dat
end

last=""
len =li.length
i =0
c=""
hatef=0
while i<len
 c=li[i,1]
 if c=='?'
  hatef=1
  ans << hate(last) 
 else
  hatef=0
  ans << last if last !='?' && i>0
  if c=='('
   /\(([^)]+)\)/ =~ li[i..-1]
   last= Or($1)
   i += $1.length+2
   next
  end
  if c=='['
   /\[([^\]]+)\]/ =~ li[i..-1]
   last = chars $1
   i += last.length+2
   next
  end
 end
 last =c
 i+=1
end
ans <<last if hatef==0

def put an,a,l,n
 if l==n
  puts an
 else
  if a[n].class==String
   an<<a[n] 
   put an,a,l,n+1
  else
   a[n].each{|i|
    if i.class==String
     put an+i,a,l,n+1 
    elsif i.class==Array
     i.each{|j|put an+j,a,l,n+1}
    end
   }
  end
 end
end

put("",ans,ans.length,0)

方針としては、バッファにブロックごとに配列に入れていく。

こんな感じ abcd(efg|hij)kl?[mn] => ["a","b","c","d",["efg","hij"],["",["k","l",["m","n"

そして、文字列に書き出す。

あまりいいとは思わないが、とりあえず。


「解説」

一文字づつ読む。解析用配列 ans。バッファには直前の文字あるいは配列。


'?'ならば => バッファが

... '?'以外ならば => バッファをansに追加、バッファは空に

... '['ならば => []の中身を文字ごとに配列にしてバッファに追加、

... '('ならば => ()の中身を'|'で切って配列にしてバッファに追加、


ans先頭から、

... 文字ならば、出力用文字列に文字を付け加えて再帰。

... 要素が配列ならば配列の要素の文字ごとに出力用文字列に付け加えて再帰。

... ansの終わりならプリント。


遅いかと思ったけれどタイムアウトにはならないので完成。

トラックバック - http://rubyist.g.hatena.ne.jp/hatecha/20071113
カレンダー
<< 2007/11 >>
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30
archive Error : RSSが取得できませんでした。