1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[Feature #18172] Add MatchData#match

The method to return the single matched substring corresponding to
the given argument.
This commit is contained in:
Nobuyoshi Nakada 2021-09-16 19:37:52 +09:00
parent ddb32e6616
commit 09d724e6f8
No known key found for this signature in database
GPG key ID: 7CD2805BFA3770C6
Notes: git 2021-09-16 21:16:17 +09:00
2 changed files with 51 additions and 0 deletions

34
re.c
View file

@ -1302,6 +1302,39 @@ match_end(VALUE match, VALUE n)
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)
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);

View file

@ -473,6 +473,23 @@ class TestRegexp < Test::Unit::TestCase
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)