From: "NARUSE, Yui" Date: 2010-05-10T07:25:47+09:00 Subject: [ruby-dev:41244] Re: 正規表現オブジェクト中のキャプチャの数 成瀬です。 (2010/05/08 15:51), KISHIMOTO, Makoto wrote: > きしもとです > > 正規表現オブジェクトからキャプチャの数を返すメソッドが欲しいです。 > (鬼車には onig_number_of_captures という関数でそういう API があります) > > static VALUE > numcaptures(VALUE re) > { > regex_t *reg = RREGEXP(re)->ptr; > int capts = onig_number_of_captures(reg); > return INT2NUM(capts); > } > > rb_define_method(rb_cRegexp, "numcaptures",&numcaptures, 0); > > どういう風に使うか、ですが、以下のようなメソッドで防御的コーディングのために > 使います。 > > class String > > def gsub_multi ptns, alts > res = [] > ptns.each{|ptn| > # ※ここでチェックしたい > re = Regexp.compile "(#{ptn.to_s})" > res<< re > } > uptn = Regexp.union *res > gsub(uptn){ > idx = $~.captures.index{|x|x} > alts[idx] > } > end > > end > > 以下のように使うメソッドです。 > > "でてこいいけのこい".gsub_multi([/こい/, /いけ/], ["いけ", "こい"]) > => "でていけこいのいけ" > (gsub の繰り返しではうまくありません) > > ここで、ptnsで与えられた正規表現中にキャプチャーがあると、インデックスが > ずれてうまくありません。なので、正規表現中にキャプチャがないことを > (いくつあるか、という情報はこの目的には過剰ですが)確認したい、 > というわけです。 onig_number_of_captures に相当するメソッドはあってもよいかなとは思うのですが、 * メソッド名 * そのユースケースでは onig_number_of_captures を使っても完全ではない が気になります。 具体的には、名前付きキャプチャが混ざった場合、そのコードは動かなくなります。 思うに、番号ではなく、名前で引いた方がいいんじゃないでしょうか。 ちなみに、Ruby 1.9 では String#gsub が拡張されていて、以下のようなことができます。 "でてこいいけのこい".gsub(/こい|いけ/, "こい"=>"いけ", "いけ"=>"こい") => "でていけこいのいけ" -- NARUSE, Yui