From: matz@... (Yukihiro Matsumoto) Date: 1996-12-06T13:54:54+09:00 Subject: [ruby-list:1207] Re: ruby 0.99.3-961204 まつもと ゆきひろです. In message "[ruby-list:1206] Re: ruby 0.99.3-961204" on 96/12/05, sinara@blade.nagaokaut.ac.jp writes: | |原です。 |> これはもともとのsuccの定義を変更すべきでしょうね. |> succって結構面倒なので,rubyで書き直したくないんですよ.せっ |> かくあるんだから. | |あれ?分からないです。「書き直したくないので定義を変更しない」 |のでは? succ はそのままに upto の定義に succ を使うのをやめた |らいいんじゃないかと思うんですけど。いまさら無理かな。 まずsuccとuptoは表裏一体なので,動きを合わせたい(jcode.rbで uptoを書き換えるならsuccも書き換えたい)のが,主な理由です. さらにuptoはperlのstring increment magicに該当する処理を行っ ているので,もともとの原さんのuptoでは仕様を満足していません. |> |後、/./ は "\n" にマッチしないので、jtr の引数には出来ません。 |> |これは仕様ということにしますか。 |> |> うーん,考えさせてください. こいつはできるようになりました.新しいjcode.rbを後ろにつけて おきます. |そういえば Perl5 で . を \n にマッチさせる /s オプションという |のが出来たのでそれを導入したらいかがでしょう。ついでに $* = 1 |に相当する /m オプションというのもあるけれど、、、。 まずrubyはいつも複数行に対応しています.つまりいつでもmオプ ションを指定していることになりますね.sオプションとかは悩ま しいですねえ. 正規表現ルーチンは借りもので中身を十分に理解していないので, あまり改造できないんですよね.本当はperl5の拡張正規表現に対 応させたり,速度を改善したいとは思っているのですけど. ASCIIだけを考えるならそんなに難しくないと思っているのですが, 日本語の取扱を考えるとちょっと私の能力を越えます.できればど なたかに助けて頂きたいですね. |それから、"abc" =~ /abc$/ と "abc\n" =~ /abc$/ は両方真です。 |後者が偽になるオプションもあったらいいかも。 perlのmオプションの逆ですね. |ついでだ。^^; 要望です。 マッチの情報を配列で返せれば満足できますか? たとえば "a;b;c;" =~ /(.);(.);(.);/ array = $~.to_a のような形で.gpickはちょっと違うもののようですけど. |さらに「反復子」のある正規表現 | |while( "abc" =~ /./g ) { print $&, "\n" } | |に相当する | |"abc".each_match(/./) { print $&, "\n" } | |もあったらいいなあ。 正規表現のgオプションは純粋に実装上の都合でなかなか難しいの ですが(スロットに空きがない),文字単位のマッチイテレータとい うのはあっても良いと思います.上のgpick相当もこれがあれば簡 単ですし. で,これは実現するにはString#grepが行単位でなく文字単位でマッ チすれば良いようにも思いますけど.どうなんでしょう? もとも とString#grepを行単位にする必然性はあまりないようですし. まつもと ゆきひろ /:|) -- jcode.rb # jcode.rb - ruby code to handle japanese (EUC/SJIS) string class String alias original_succ succ private :original_succ def succ if self[-2] && self[-2] & 0x80 != 0 s = self.dup s[-1] += 1 return s else original_succ end end def upto(to) return if self > to curr = self tail = self[-2..-1] if tail.length == 2 and tail =~ /^.$/ then if self[0..-2] == to[0..-2] for c in self[-1] .. to[-1] yield self[0..-2]+c.chr end end else loop do yield curr return if curr == to curr = curr.succ return if curr.length > to.length end end return nil end def _expand_ch a = [] split(/(.-.)|/).each do |r| if r =~ /(.)-(.)/ if $1.length != $2.length next elsif $1.length == 1 $1[0].upto($2[0]) { |c| a.push c.chr } else $1.upto($2) { |c| a.push c } end elsif r.length > 0 a.push r end end a end def tr(from, to) afrom = from._expand_ch ato = to._expand_ch i = 0 self.split(//).collect{ |c| if i = afrom.index(c) if i < ato.size then ato[i] else ato[-1] end else c end }.join("") end alias jtr tr end