Regexp#names, MatchData#names, MatchData#regexp

named capture e$B$^$o$j$r$=$m$($F$$$F!"$d$O$jL>A0$N%j%9%H$rF@$ke(B
e$B%a%=%C%I$,I,MW$@$m$&$H$$$&$3$H$G!“e(BRegexp#names e$B$He(B
MatchData#names e$B$r<BAu$7$F$_$^$7$?$,!”$I$&$G$7$g$&$+!#e(B

e$B$"$H!“e(Bmatch.names e$B$Oe(B match.regexp.names
e$B$HF1$8!”$H%I%-%e%a%se(B
e$B%H$K=q$3$&$H$7$?$N$G$9$,e(B MatchData#regexp e$B$,$J$+$C$?$N$G$3$le(B
e$B$b$D$1$^$7$?!#e(B

Index: re.c

— re.c (revision 14159)
+++ re.c (working copy)
@@ -513,6 +513,38 @@ rb_reg_options_m(VALUE re)
return INT2NUM(options);
}

+static int
+reg_names_iter(const OnigUChar *name, const OnigUChar *name_end,

  •      int back_num, int *back_refs, OnigRegex regex, void *arg)
    

+{

  • VALUE ary = (VALUE)arg;
  • rb_ary_push(ary, rb_str_new((const char *)name, name_end-name));
  • return 0;
    +}

+/*

    • call-seq:
    • rxp.names => [name1, name2, …]
    • Returns an array of names of named captures.
    • /(?<foo>.)(?<bar>.)(?<baz>.)/.names
      
    • #=> ["foo", "bar", "baz"]
      
    • /(?<foo>.)(?<foo>.)/.names
      
    • #=> ["foo"]
      
    • /(.)(.)/.names'
      
    • #=> []
      
  • */

+static VALUE
+rb_reg_names(VALUE re)
+{

  • VALUE ary = rb_ary_new();
  • onig_foreach_name(RREGEXP(re)->ptr, reg_names_iter, (void*)ary);
  • return ary;
    +}

static Regexp*
make_regexp(const char *s, long len, rb_encoding *enc, int flags,
onig_errmsg_buffer err)
@@ -595,6 +627,42 @@ match_init_copy(VALUE obj, VALUE orig)

/*

    • call-seq:
    • mtch.regexp => regexp
    • Returns the regexp.
    • m = /a.*b/.match("abc")
      
    • m.regexp #=> /a.*b/
      
  • */

+static VALUE
+match_regexp(VALUE match)
+{

  • return RMATCH(match)->regexp;
    +}

+/*

    • call-seq:
    • mtch.names => [name1, name2, …]
    • Returns an array of names of named captures.
    • It is same as mtch.regexp.names.
    • /(?<foo>.)(?<bar>.)(?<baz>.)/.match("hoge").names
      
    • #=> ["foo", "bar", "baz"]
      
    • m = /(?<x>.)(?<y>.)?/.match("a") #=> #<MatchData "a" x:"a" 
      

y:nil>

    • m.names                          #=> ["x", "y"]
      
  • */

+static VALUE
+match_names(VALUE match)
+{

  • return rb_reg_names(RMATCH(match)->regexp);
    +}

+/*

  • call-seq:
  • mtch.length   => integer
    
  • mtch.size     => integer
    

@@ -2754,6 +2822,7 @@ Init_Regexp(void)
rb_define_method(rb_cRegexp, “options”, rb_reg_options_m, 0);
rb_define_method(rb_cRegexp, “encoding”, rb_obj_encoding, 0); /* in
encoding.c */
rb_define_method(rb_cRegexp, “fixed_encoding?”,
rb_reg_fixed_encoding_p, 0);

  • rb_define_method(rb_cRegexp, “names”, rb_reg_names, 0);

    rb_define_const(rb_cRegexp, “IGNORECASE”,
    INT2FIX(ONIG_OPTION_IGNORECASE));
    rb_define_const(rb_cRegexp, “EXTENDED”,
    INT2FIX(ONIG_OPTION_EXTEND));
    @@ -2766,6 +2835,8 @@ Init_Regexp(void)
    rb_undef_method(CLASS_OF(rb_cMatch), “new”);

    rb_define_method(rb_cMatch, “initialize_copy”, match_init_copy, 1);

  • rb_define_method(rb_cMatch, “regexp”, match_regexp, 0);

  • rb_define_method(rb_cMatch, “names”, match_names, 0);
    rb_define_method(rb_cMatch, “size”, match_size, 0);
    rb_define_method(rb_cMatch, “length”, match_size, 0);
    rb_define_method(rb_cMatch, “offset”, match_offset, 1);

In article [email protected],
Tanaka A. [email protected] writes:

named capture e$B$^$o$j$r$=$m$($F$$$F!"$d$O$jL>A0$N%j%9%H$rF@$ke(B
e$B%a%=%C%I$,I,MW$@$m$&$H$$$&$3$H$G!“e(BRegexp#names e$B$He(B
MatchData#names e$B$r<BAu$7$F$_$^$7$?$,!”$I$&$G$7$g$&$+!#e(B

e$B$"$H!“e(Bmatch.names e$B$Oe(B match.regexp.names e$B$HF1$8!”$H%I%-%e%a%se(B
e$B%H$K=q$3$&$H$7$?$N$G$9$,e(B MatchData#regexp e$B$,$J$+$C$?$N$G$3$le(B
e$B$b$D$1$^$7$?!#e(B

e$B$&$%$`!#e(BMatchData#pretty_print e$B$GL>A0$b=P$=$&$H;W$C$?$ie(B
names e$B$@$1$G$O>pJs$,B-$j$J$+$C$?$N$G!“e(BRegexp#named_captures
e$B$GL>A0$+$i%$%s%G%C%/%9$N%j%9%H$X$N%O%C%7%e$rJV$9$h$&$K$7$F$_e(B
e$B$^$7$?!#$3$N7A$O54<V$,e(B onig_foreach_name e$B$GDs6!$7$F$/$l$k$be(B
e$B$N$H4pK\E*$KF1$8$G$9!#e(B
(e$B$J$*!”$3$3$G$be(B MatchData#regexp e$B$,I,MW$K$J$j$^$7$?!#e(B)

e$B$I$&$G$7$g$&$+!#e(B

Index: re.c

— re.c (revision 14161)
+++ re.c (working copy)
@@ -523,6 +523,84 @@ rb_reg_options_m(VALUE re)
return INT2NUM(options);
}

+static int
+reg_names_iter(const OnigUChar *name, const OnigUChar *name_end,

  •      int back_num, int *back_refs, OnigRegex regex, void *arg)
    

+{

  • VALUE ary = (VALUE)arg;
  • rb_ary_push(ary, rb_str_new((const char *)name, name_end-name));
  • return 0;
    +}

+/*

    • call-seq:
    • rxp.names => [name1, name2, …]
    • Returns a list of names of captures as an array of strings.
    • /(?<foo>.)(?<bar>.)(?<baz>.)/.names
      
    • #=> ["foo", "bar", "baz"]
      
    • /(?<foo>.)(?<foo>.)/.names
      
    • #=> ["foo"]
      
    • /(.)(.)/.names'
      
    • #=> []
      
  • */

+static VALUE
+rb_reg_names(VALUE re)
+{

  • VALUE ary = rb_ary_new();
  • onig_foreach_name(RREGEXP(re)->ptr, reg_names_iter, (void*)ary);
  • return ary;
    +}

+static int
+reg_named_captures_iter(const OnigUChar *name, const OnigUChar
*name_end,

  •      int back_num, int *back_refs, OnigRegex regex, void *arg)
    

+{

  • VALUE hash = (VALUE)arg;
  • VALUE ary = rb_ary_new2(back_num);
  • int i;
  • for(i = 0; i < back_num; i++)
  •    rb_ary_store(ary, i, INT2NUM(back_refs[i]));
    
  • rb_hash_aset(hash, rb_str_new((const char*)name,
    name_end-name),ary);
  • return 0;
    +}

+/*

    • call-seq:
    • rxp.named_captures => hash
    • Returns a hash representing information about named captures of
      rxp.
    • A key of the hash is a name of the named captures.
    • A value of the hash is an array which is list of indexes of
      corresponding
    • named captures.
    • /(?.)(?.)/.named_captures
    • #=> {“foo”=>[1], “bar”=>[2]}
    • /(?.)(?.)/.named_captures’
    • #=> {“foo”=>[1, 2]}
    • If there are no named captures, an empty hash is returned.
    • /(.)(.)/.named_captures’
    • #=> {}
  • */

+static VALUE
+rb_reg_named_captures(VALUE re)
+{

  • VALUE hash = rb_hash_new();
  • onig_foreach_name(RREGEXP(re)->ptr, reg_named_captures_iter,
    (void*)hash);
  • return hash;
    +}

static Regexp*
make_regexp(const char *s, long len, rb_encoding *enc, int flags,
onig_errmsg_buffer err)
@@ -604,6 +682,42 @@ match_init_copy(VALUE obj, VALUE orig)

/*

    • call-seq:
    • mtch.regexp => regexp
    • Returns the regexp.
    • m = /a.*b/.match("abc")
      
    • m.regexp #=> /a.*b/
      
  • */

+static VALUE
+match_regexp(VALUE match)
+{

  • return RMATCH(match)->regexp;
    +}

+/*

    • call-seq:
    • mtch.names => [name1, name2, …]
    • Returns a list of names of captures as an array of strings.
    • It is same as mtch.regexp.names.
    • /(?<foo>.)(?<bar>.)(?<baz>.)/.match("hoge").names
      
    • #=> ["foo", "bar", "baz"]
      
    • m = /(?<x>.)(?<y>.)?/.match("a") #=> #<MatchData "a" x:"a" 
      

y:nil>

    • m.names                          #=> ["x", "y"]
      
  • */

+static VALUE
+match_names(VALUE match)
+{

  • return rb_reg_names(RMATCH(match)->regexp);
    +}

+/*

  • call-seq:
  • mtch.length   => integer
    
  • mtch.size     => integer
    

@@ -1362,11 +1476,12 @@ match_inspect(VALUE match)
int i;
int num_regs = RMATCH(match)->regs->num_regs;
struct backref_name_tag *names;

  • VALUE regexp = RMATCH(match)->regexp;

    names = ALLOCA_N(struct backref_name_tag, num_regs);
    MEMZERO(names, struct backref_name_tag, num_regs);

  • onig_foreach_name(RREGEXP(RMATCH(match)->regexp)->ptr,
  • onig_foreach_name(RREGEXP(regexp)->ptr,
    match_inspect_name_iter, names);

    str = rb_str_buf_new2(“#<”);
    @@ -2818,6 +2933,8 @@ Init_Regexp(void)
    rb_define_method(rb_cRegexp, “options”, rb_reg_options_m, 0);
    rb_define_method(rb_cRegexp, “encoding”, rb_obj_encoding, 0); /* in
    encoding.c */
    rb_define_method(rb_cRegexp, “fixed_encoding?”,
    rb_reg_fixed_encoding_p, 0);

  • rb_define_method(rb_cRegexp, “names”, rb_reg_names, 0);

  • rb_define_method(rb_cRegexp, “named_captures”,
    rb_reg_named_captures, 0);

    rb_define_const(rb_cRegexp, “IGNORECASE”,
    INT2FIX(ONIG_OPTION_IGNORECASE));
    rb_define_const(rb_cRegexp, “EXTENDED”,
    INT2FIX(ONIG_OPTION_EXTEND));
    @@ -2830,6 +2947,8 @@ Init_Regexp(void)
    rb_undef_method(CLASS_OF(rb_cMatch), “new”);

    rb_define_method(rb_cMatch, “initialize_copy”, match_init_copy, 1);

  • rb_define_method(rb_cMatch, “regexp”, match_regexp, 0);

  • rb_define_method(rb_cMatch, “names”, match_names, 0);
    rb_define_method(rb_cMatch, “size”, match_size, 0);
    rb_define_method(rb_cMatch, “length”, match_size, 0);
    rb_define_method(rb_cMatch, “offset”, match_offset, 1);
    Index: lib/pp.rb
    ===================================================================
    — lib/pp.rb (revision 14161)
    +++ lib/pp.rb (working copy)
    @@ -473,10 +473,24 @@ end

class MatchData
def pretty_print(q)

  • nc = []
  • self.regexp.named_captures.each {|name, indexes|
  •  indexes.each {|i| nc[i] = name }
    
  • }
    q.object_group(self) {
    q.breakable
  •  q.seplist(1..self.size, lambda { q.breakable }) {|i|
    
  •    q.pp self[i-1]
    
  •  q.seplist(0...self.size, lambda { q.breakable }) {|i|
    
  •    if i == 0
    
  •      q.pp self[i]
    
  •    else
    
  •      if nc[i]
    
  •        q.text nc[i]
    
  •      else
    
  •        q.pp i
    
  •      end
    
  •      q.text ':'
    
  •      q.pp self[i]
    
  •    end
     }
    
    }
    end

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:32494] Re: Regexp#names, MatchData#names,
MatchData#regexp”
on Mon, 10 Dec 2007 00:08:14 +0900, Tanaka A. [email protected]
writes:
|
|In article [email protected],
| Tanaka A. [email protected] writes:
|
|> named capture e$B$^$o$j$r$=$m$($F$$$F!“$d$O$jL>A0$N%j%9%H$rF@$ke(B
|> e$B%a%=%C%I$,I,MW$@$m$&$H$$$&$3$H$G!“e(BRegexp#names e$B$He(B
|> MatchData#names e$B$r<BAu$7$F$_$^$7$?$,!”$I$&$G$7$g$&$+!#e(B
|>
|> e$B$”$H!“e(Bmatch.names e$B$Oe(B match.regexp.names e$B$HF1$8!”$H%I%-%e%a%se(B
|> e$B%H$K=q$3$&$H$7$?$N$G$9$,e(B MatchData#regexp e$B$,$J$+$C$?$N$G$3$le(B
|> e$B$b$D$1$^$7$?!#e(B
|
|e$B$&$%$`!#e(BMatchData#pretty_print e$B$GL>A0$b=P$=$&$H;W$C$?$ie(B
|names e$B$@$1$G$O>pJs$,B-$j$J$+$C$?$N$G!“e(BRegexp#named_captures
|e$B$GL>A0$+$i%$%s%G%C%/%9$N%j%9%H$X$N%O%C%7%e$rJV$9$h$&$K$7$F$_e(B
|e$B$^$7$?!#$3$N7A$O54<V$,e(B onig_foreach_name e$B$GDs6!$7$F$/$l$k$be(B
|e$B$N$H4pK\E*$KF1$8$G$9!#e(B
|(e$B$J$*!”$3$3$G$be(B MatchData#regexp e$B$,I,MW$K$J$j$^$7$?!#e(B)
|
|e$B$I$&$G$7$g$&$+!#e(B

named capturee$B$O<j$D$+$:$@$C$?$N$G=u$+$j$^$9!#e(B
[ruby-dev:32493]e$B$H$b$I$b%3%_%C%H$7$F$/$@$5$$!#e(B