Project

General

Profile

11999.diff

sorah (Sorah Fukumori), 01/18/2016 08:55 AM

View differences:

re.c
1931 1931
    return str;
1932 1932
}
1933 1933

  
1934
static int
1935
match_to_h_iter(const OnigUChar *name, const OnigUChar *name_end,
1936
	int back_num, int *back_refs, OnigRegex regex, void *arg) {
1937
    struct MEMO *memo = MEMO_CAST(arg);
1938
    VALUE hash = memo->v1;
1939
    VALUE match = memo->v2;
1940

  
1941
    VALUE key = rb_enc_str_new((const char *)name, name_end-name, regex->enc);
1942
    VALUE value = rb_reg_nth_match(back_refs[back_num-1], match);
1943

  
1944
    rb_hash_aset(hash, key, value);
1945
    return 0;
1946
}
1947

  
1948
/*
1949
 *  call-seq:
1950
 *     mtch.to_h   -> hash
1951
 *
1952
 *  Returns a Hash using named capture.
1953
 *
1954
 *  A key of the hash is a name of the named captures.
1955
 *  A value of the hash is a string of last capture of corresponding group.
1956
 *
1957
 *     m = /(?<a>.)(?<b>.)/.match("01")
1958
 *     m.to_h   #=> {"a" => "0", "b" => "1"}
1959
 *
1960
 *     m = /(?<a>.)(?<b>.)?/.match("0")
1961
 *     m.to_h   #=> {"a" => "0", "b" => nil}
1962
 *
1963
 *     m = /(?<a>.)(?<a>.)/.match("01")
1964
 *     m.to_h   #=> {"a" => "1"}
1965
 */
1966

  
1967
static VALUE
1968
match_to_h(VALUE match)
1969
{
1970
    VALUE hash;
1971
    struct MEMO *memo;
1972

  
1973
    match_check(match);
1974

  
1975
    hash = rb_hash_new();
1976
    memo = MEMO_NEW(hash, match, 0);
1977

  
1978
    onig_foreach_name(RREGEXP(RMATCH(match)->regexp)->ptr, match_to_h_iter, (void*)memo);
1979

  
1980
    return hash;
1981
}
1934 1982

  
1935 1983
/*
1936 1984
 *  call-seq:
......
3750 3798
    rb_define_method(rb_cMatch, "pre_match", rb_reg_match_pre, 0);
3751 3799
    rb_define_method(rb_cMatch, "post_match", rb_reg_match_post, 0);
3752 3800
    rb_define_method(rb_cMatch, "to_s", match_to_s, 0);
3801
    rb_define_method(rb_cMatch, "to_h", match_to_h, 0);
3753 3802
    rb_define_method(rb_cMatch, "inspect", match_inspect, 0);
3754 3803
    rb_define_method(rb_cMatch, "string", match_string, 0);
3755 3804
    rb_define_method(rb_cMatch, "hash", match_hash, 0);
test/ruby/test_regexp.rb
173 173
    assert_raise(IndexError, bug9903) {m[key.dup.force_encoding(Encoding::Shift_JIS)]}
174 174
  end
175 175

  
176
  def test_named_capture_to_h
177
    assert_equal({'a' => '1', 'b' => '2', 'c' => nil}, /^(?<a>.)(?<b>.)(?<c>.)?/.match('12').to_h)
178
    assert_equal({'a' => '1', 'b' => '2', 'c' => '3'}, /^(?<a>.)(?<b>.)(?<c>.)?/.match('123').to_h)
179
    assert_equal({'a' => '1', 'b' => '2', 'c' => ''}, /^(?<a>.)(?<b>.)(?<c>.?)/.match('12').to_h)
180

  
181
    assert_equal({'a' => '1', 'b' => '2'}, /^(.)(?<a>.)(?<b>.)/.match('012').to_h)
182
    assert_equal({'a' => '2'}, /^(?<a>.)(?<a>.)/.match('12').to_h)
183
  end
184

  
176 185
  def test_assign_named_capture
177 186
    assert_equal("a", eval('/(?<foo>.)/ =~ "a"; foo'))
178 187
    assert_equal("a", eval('foo = 1; /(?<foo>.)/ =~ "a"; foo'))