ruby-changes:68012
From: Nobuyoshi <ko1@a...>
Date: Thu, 16 Sep 2021 21:16:09 +0900 (JST)
Subject: [ruby-changes:68012] 09d724e6f8 (master): [Feature #18172] Add MatchData#match
https://git.ruby-lang.org/ruby.git/commit/?id=09d724e6f8 From 09d724e6f846b4e53e8571d41ca7d3055d732d9f Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Thu, 16 Sep 2021 19:37:52 +0900 Subject: [Feature #18172] Add MatchData#match The method to return the single matched substring corresponding to the given argument. --- re.c | 34 ++++++++++++++++++++++++++++++++++ test/ruby/test_regexp.rb | 17 +++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/re.c b/re.c index 5c5b53d..5d5f6fc 100644 --- a/re.c +++ b/re.c @@ -1302,6 +1302,39 @@ match_end(VALUE match, VALUE n) https://github.com/ruby/ruby/blob/trunk/re.c#L1302 return INT2FIX(RMATCH(match)->rmatch->char_offset[i].end); } +/* + * call-seq: + * mtch.match(n) -> string or nil + * + * Returns the captured substring corresponding to the argument. + * <em>n</em> can be a string or symbol to reference a named capture. + * + * m = /(.)(.)(\d+)(\d)(\w)?/.match("THX1138.") + * m.match(0) #=> "HX1138" + * m.match(4) #=> "8" + * m.match(5) #=> nil + * + * m = /(?<foo>.)(.)(?<bar>.+)/.match("hoge") + * m.match(:foo) #=> "h" + * m.match(:bar) #=> "ge" + * + */ + +static VALUE +match_nth(VALUE match, VALUE n) +{ + int i = match_backref_number(match, n); + struct re_registers *regs = RMATCH_REGS(match); + + backref_number_check(regs, i); + + long start = BEG(i), end = END(i); + if (start < 0) + return Qnil; + + return rb_str_subseq(RMATCH(match)->str, start, end - start); +} + #define MATCH_BUSY FL_USER2 void @@ -4102,6 +4135,7 @@ Init_Regexp(void) https://github.com/ruby/ruby/blob/trunk/re.c#L4135 rb_define_method(rb_cMatch, "offset", match_offset, 1); rb_define_method(rb_cMatch, "begin", match_begin, 1); rb_define_method(rb_cMatch, "end", match_end, 1); + rb_define_method(rb_cMatch, "match", match_nth, 1); rb_define_method(rb_cMatch, "to_a", match_to_a, 0); rb_define_method(rb_cMatch, "[]", match_aref, -1); rb_define_method(rb_cMatch, "captures", match_captures, 0); diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb index af62d94..66a60b8 100644 --- a/test/ruby/test_regexp.rb +++ b/test/ruby/test_regexp.rb @@ -473,6 +473,23 @@ class TestRegexp < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_regexp.rb#L473 assert_equal("foobarbaz", m.string) end + def test_match_matchsubstring + m = /(.)(.)(\d+)(\d)(\w)?/.match("THX1138.") + assert_equal("HX1138", m.match(0)) + assert_equal("8", m.match(4)) + assert_nil(m.match(5)) + + m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044") + assert_equal("\u3043", m.match(1)) + assert_nil(m.match(2)) + assert_equal("\u3044", m.match(3)) + + m = /(?<foo>.)(?<n>[^aeiou])?(?<bar>.+)/.match("hoge\u3042") + assert_equal("h", m.match(:foo)) + assert_nil(m.match(:n)) + assert_equal("oge\u3042", m.match(:bar)) + end + def test_match_inspect m = /(...)(...)(...)(...)?/.match("foobarbaz") assert_equal('#<MatchData "foobarbaz" 1:"foo" 2:"bar" 3:"baz" 4:nil>', m.inspect) -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/