Ruby 2.4

MatchData

MatchData 类

Parent:Object

MatchData是特殊变量$~的类型,并且是由Regexp#match&返回的对象的类型Regexp.last_match。它封装模式匹配的所有结果,结果通常是通过特殊的变量访问$&$'$`$1$2,等。

公共实例方法

mtch == mtch2→true 或 false 显示来源

平等 - 如果两个匹配数据的目标字符串,模式和匹配位置相同,则两个匹配数据相等。

static VALUE match_equal(VALUE match1, VALUE match2) { const struct re_registers *regs1, *regs2; if (match1 == match2) return Qtrue; if (!RB_TYPE_P(match2, T_MATCH)) return Qfalse; if (!RMATCH(match1)->regexp || !RMATCH(match2)->regexp) return Qfalse; if (!rb_str_equal(RMATCH(match1)->str, RMATCH(match2)->str)) return Qfalse; if (!rb_reg_equal(match_regexp(match1), match_regexp(match2))) return Qfalse; regs1 = RMATCH_REGS(match1 regs2 = RMATCH_REGS(match2 if (regs1->num_regs != regs2->num_regs) return Qfalse; if (memcmp(regs1->beg, regs2->beg, regs1->num_regs * sizeof(*regs1->beg))) return Qfalse; if (memcmp(regs1->end, regs2->end, regs1->num_regs * sizeof(*regs1->end))) return Qfalse; return Qtrue; }

mtchi → str or nil Show source

mtchstart, length → array

mtchrange → array

mtchname → str or nil

匹配引用 - MatchData用作数组,可以使用普通数组索引技术访问。mtch[0]等价于特殊变量$&,并返回整个匹配的字符串。mtch[1]mtch[2]等等,返回匹配的反向引用的值(圆括号之间的模式部分)。

m = /(.)(.)(\d+)(\d)/.match("THX1138.") m #=> #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8"> m[0] #=> "HX1138" m[1, 2] #=> ["H", "X"] m[1..3] #=> ["H", "X", "113"] m[-3, 2] #=> ["X", "113"] m = /(?<foo>a+)b/.match("ccaaab") m #=> #<MatchData "aaab" foo:"aaa"> m["foo"] #=> "aaa" m[:foo] #=> "aaa"

static VALUE match_aref(int argc, VALUE *argv, VALUE match) { VALUE idx, length; match_check(match rb_scan_args(argc, argv, "11", &idx, &length if (NIL_P(length)) { if (FIXNUM_P(idx)) { return rb_reg_nth_match(FIX2INT(idx), match } else { int num = namev_to_backref_number(RMATCH_REGS(match), RMATCH(match)->regexp, idx if (num >= 0) { return rb_reg_nth_match(num, match } else { return match_ary_aref(match, idx, Qnil } } } else { long beg = NUM2LONG(idx long len = NUM2LONG(length long num_regs = RMATCH_REGS(match)->num_regs; if (len < 0) { return Qnil; } if (beg < 0) { beg += num_regs; if (beg < 0) return Qnil; } else if (beg > num_regs) { return Qnil; } else if (beg+len > num_regs) { len = num_regs - beg; } return match_ary_subseq(match, beg, len, Qnil } }

begin(n) → integer Show source

返回字符串中匹配数组的第 n 个元素的开始位置的偏移量。_n 可以是一个字符串或符号来引用一个命名的捕获。

m = /(.)(.)(\d+)(\d)/.match("THX1138.") m.begin(0) #=> 1 m.begin(2) #=> 2 m = /(?<foo>.)(.)(?<bar>.)/.match("hoge") p m.begin(:foo) #=> 0 p m.begin(:bar) #=> 2

static VALUE match_begin(VALUE match, VALUE n) { int i = match_backref_number(match, n struct re_registers *regs = RMATCH_REGS(match match_check(match if (i < 0 || regs->num_regs <= i) rb_raise(rb_eIndexError, "index %d out of matches", i if (BEG(i) < 0) return Qnil; update_char_offset(match return INT2FIX(RMATCH(match)->rmatch->char_offset[i].beg }

captures → array Show source

返回捕获数组; 相当于mtch.to_a[1..-1]

f1,f2,f3,f4 = /(.)(.)(\d+)(\d)/.match("THX1138.").captures f1 #=> "H" f2 #=> "X" f3 #=> "113" f4 #=> "8"

static VALUE match_captures(VALUE match) { return match_array(match, 1 }

end(n) → integer Show source

返回紧跟在字符串中匹配数组的第 n 个元素的结尾之后的字符的偏移量。_n 可以是一个字符串或符号来引用一个命名的捕获。

m = /(.)(.)(\d+)(\d)/.match("THX1138.") m.end(0) #=> 7 m.end(2) #=> 3 m = /(?<foo>.)(.)(?<bar>.)/.match("hoge") p m.end(:foo) #=> 1 p m.end(:bar) #=> 3

static VALUE match_end(VALUE match, VALUE n) { int i = match_backref_number(match, n struct re_registers *regs = RMATCH_REGS(match match_check(match if (i < 0 || regs->num_regs <= i) rb_raise(rb_eIndexError, "index %d out of matches", i if (BEG(i) < 0) return Qnil; update_char_offset(match return INT2FIX(RMATCH(match)->rmatch->char_offset[i].end }

eql?(mtch2) → true or false Show source

平等 - 如果两个匹配数据的目标字符串,模式和匹配位置相同,则两个匹配数据相等。

static VALUE match_equal(VALUE match1, VALUE match2) { const struct re_registers *regs1, *regs2; if (match1 == match2) return Qtrue; if (!RB_TYPE_P(match2, T_MATCH)) return Qfalse; if (!RMATCH(match1)->regexp || !RMATCH(match2)->regexp) return Qfalse; if (!rb_str_equal(RMATCH(match1)->str, RMATCH(match2)->str)) return Qfalse; if (!rb_reg_equal(match_regexp(match1), match_regexp(match2))) return Qfalse; regs1 = RMATCH_REGS(match1 regs2 = RMATCH_REGS(match2 if (regs1->num_regs != regs2->num_regs) return Qfalse; if (memcmp(regs1->beg, regs2->beg, regs1->num_regs * sizeof(*regs1->beg))) return Qfalse; if (memcmp(regs1->end, regs2->end, regs1->num_regs * sizeof(*regs1->end))) return Qfalse; return Qtrue; }

hash → integer Show source

根据目标字符串,regexp 和匹配的匹配位置产生一个散列。

另请参阅对象#散列。

static VALUE match_hash(VALUE match) { const struct re_registers *regs; st_index_t hashval; match_check(match hashval = rb_hash_start(rb_str_hash(RMATCH(match)->str) hashval = rb_hash_uint(hashval, reg_hash(match_regexp(match)) regs = RMATCH_REGS(match hashval = rb_hash_uint(hashval, regs->num_regs hashval = rb_hash_uint(hashval, rb_memhash(regs->beg, regs->num_regs * sizeof(*regs->beg)) hashval = rb_hash_uint(hashval, rb_memhash(regs->end, regs->num_regs * sizeof(*regs->end)) hashval = rb_hash_end(hashval return ST2FIX(hashval }

inspect → str Show source

返回可打印版本的 mtch。

puts /.$/.match("foo").inspect #=> #<MatchData "o"> puts /(.)(.)(.)/.match("foo").inspect #=> #<MatchData "foo" 1:"f" 2:"o" 3:"o"> puts /(.)(.)?(.)/.match("fo").inspect #=> #<MatchData "fo" 1:"f" 2:nil 3:"o"> puts /(?<foo>.)(?<bar>.)(?<baz>.)/.match("hoge").inspect #=> #<MatchData "hog" foo:"h" bar:"o" baz:"g">

static VALUE match_inspect(VALUE match) { VALUE cname = rb_class_path(rb_obj_class(match) VALUE str; int i; struct re_registers *regs = RMATCH_REGS(match int num_regs = regs->num_regs; struct backref_name_tag *names; VALUE regexp = RMATCH(match)->regexp; if (regexp == 0) { return rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)match } else if (NIL_P(regexp)) { return rb_sprintf("#<%"PRIsVALUE": %"PRIsVALUE">", cname, rb_reg_nth_match(0, match) } names = ALLOCA_N(struct backref_name_tag, num_regs MEMZERO(names, struct backref_name_tag, num_regs onig_foreach_name(RREGEXP_PTR(regexp), match_inspect_name_iter, names str = rb_str_buf_new2("#<" rb_str_append(str, cname for (i = 0; i < num_regs; i++) { VALUE v; rb_str_buf_cat2(str, " " if (0 < i) { if (names[i].name) rb_str_buf_cat(str, (const char *)names[i].name, names[i].len else { rb_str_catf(str, "%d", i } rb_str_buf_cat2(str, ":" } v = rb_reg_nth_match(i, match if (v == Qnil) rb_str_buf_cat2(str, "nil" else rb_str_buf_append(str, rb_str_inspect(v) } rb_str_buf_cat2(str, ">" return str; }

length → integer Show source

返回匹配数组中元素的数量。

m = /(.)(.)(\d+)(\d)/.match("THX1138.") m.length #=> 5 m.size #=> 5

static VALUE match_size(VALUE match) { match_check(match return INT2FIX(RMATCH_REGS(match)->num_regs }

named_captures → hash Show source

使用命名捕获返回哈希。

散列的一个关键是指定捕获的名称。散列值是对应组最后一次成功捕获的字符串。

m = /(?<a>.)(?<b>.)/.match("01") m.named_captures #=> {"a" => "0", "b" => "1"} m = /(?<a>.)(?<b>.)?/.match("0") m.named_captures #=> {"a" => "0", "b" => nil} m = /(?<a>.)(?<a>.)/.match("01") m.named_captures #=> {"a" => "1"} m = /(?<a>x)|(?<a>y)/.match("x") m.named_captures #=> {"a" => "x"}

static VALUE match_named_captures(VALUE match) { VALUE hash; struct MEMO *memo; match_check(match if (NIL_P(RMATCH(match)->regexp)) return rb_hash_new( hash = rb_hash_new( memo = MEMO_NEW(hash, match, 0 onig_foreach_name(RREGEXP(RMATCH(match)->regexp)->ptr, match_named_captures_iter, (void*)memo return hash; }

names → name1, name2, ...()

以字符串数组的形式返回捕获的名称列表。它与 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) { match_check(match if (NIL_P(RMATCH(match)->regexp)) return rb_ary_new_capa(0 return rb_reg_names(RMATCH(match)->regexp }

offset(n) → array Show source

返回包含第 n 个匹配的开始和结束偏移量的双元素数组。_n 可以是一个字符串或符号来引用一个命名的捕获。

m = /(.)(.)(\d+)(\d)/.match("THX1138.") m.offset(0) #=> [1, 7] m.offset(4) #=> [6, 7] m = /(?<foo>.)(.)(?<bar>.)/.match("hoge") p m.offset(:foo) #=> [0, 1] p m.offset(:bar) #=> [2, 3]

static VALUE match_offset(VALUE match, VALUE n) { int i = match_backref_number(match, n struct re_registers *regs = RMATCH_REGS(match match_check(match if (i < 0 || regs->num_regs <= i) rb_raise(rb_eIndexError, "index %d out of matches", i if (BEG(i) < 0) return rb_assoc_new(Qnil, Qnil update_char_offset(match return rb_assoc_new(INT2FIX(RMATCH(match)->rmatch->char_offset[i].beg), INT2FIX(RMATCH(match)->rmatch->char_offset[i].end) }

post_match → str Show source

返回当前匹配后原始字符串的部分。等同于特殊变量$'

m = /(.)(.)(\d+)(\d)/.match("THX1138: The Movie") m.post_match #=> ": The Movie"

VALUE rb_reg_match_post(VALUE match) { VALUE str; long pos; struct re_registers *regs; if (NIL_P(match)) return Qnil; match_check(match regs = RMATCH_REGS(match if (BEG(0) == -1) return Qnil; str = RMATCH(match)->str; pos = END(0 str = rb_str_subseq(str, pos, RSTRING_LEN(str) - pos if (OBJ_TAINTED(match)) OBJ_TAINT(str return str; }

pre_match → str Show source

返回当前匹配之前原始字符串的部分。等同于特殊变量$`

m = /(.)(.)(\d+)(\d)/.match("THX1138.") m.pre_match #=> "T"

VALUE rb_reg_match_pre(VALUE match) { VALUE str; struct re_registers *regs; if (NIL_P(match)) return Qnil; match_check(match regs = RMATCH_REGS(match if (BEG(0) == -1) return Qnil; str = rb_str_subseq(RMATCH(match)->str, 0, BEG(0) if (OBJ_TAINTED(match)) OBJ_TAINT(str return str; }

regexp → regexp Show source

返回正则表达式。

m = /a.*b/.match("abc") m.regexp #=> /a.*b/

static VALUE match_regexp(VALUE match) { VALUE regexp; match_check(match regexp = RMATCH(match)->regexp; if (NIL_P(regexp)) { VALUE str = rb_reg_nth_match(0, match regexp = rb_reg_regcomp(rb_reg_quote(str) RMATCH(match)->regexp = regexp; } return regexp; }

size → integer Show source

返回匹配数组中元素的数量。

m = /(.)(.)(\d+)(\d)/.match("THX1138.") m.length #=> 5 m.size #=> 5

static VALUE match_size(VALUE match) { match_check(match return INT2FIX(RMATCH_REGS(match)->num_regs }

string → str Show source

返回传入的字符串的冻结副本match

m = /(.)(.)(\d+)(\d)/.match("THX1138.") m.string #=> "THX1138."

static VALUE match_string(VALUE match) { match_check(match return RMATCH(match)->str; /* str is frozen */ }

to_a → anArray Show source

返回匹配数组。

m = /(.)(.)(\d+)(\d)/.match("THX1138.") m.to_a #=> ["HX1138", "H", "X", "113", "8"]

由于to_a在展开*变量时调用,因此有一个用于提取匹配字段的有用分配快捷方式。这比直接访问字段稍慢(因为生成了中间数组)。

all,f1,f2,f3 = * /(.)(.)(\d+)(\d)/.match("THX1138.") all #=> "HX1138" f1 #=> "H" f2 #=> "X" f3 #=> "113"

static VALUE match_to_a(VALUE match) { return match_array(match, 0 }

to_s → str Show source

返回整个匹配的字符串。

m = /(.)(.)(\d+)(\d)/.match("THX1138.") m.to_s #=> "HX1138"

static VALUE match_to_s(VALUE match) { VALUE str = rb_reg_last_match(match match_check(match if (NIL_P(str)) str = rb_str_new(0,0 if (OBJ_TAINTED(match)) OBJ_TAINT(str if (OBJ_TAINTED(RMATCH(match)->str)) OBJ_TAINT(str return str; }

values_at(index*) → array Show source

使用每个索引访问匹配值,返回相应匹配的数组。

m = /(.)(.)(\d+)(\d)/.match("THX1138: The Movie") m.to_a #=> ["HX1138", "H", "X", "113", "8"] m.values_at(0, 2, -2) #=> ["HX1138", "X", "113"] m = /(?<a>\d+) *(?<op>[+\-*\/]) *(?<b>\d+)/.match("1 + 2") m.to_a #=> ["1 + 2", "1", "+", "2"] m.values_at(:a, :b, :op) #=> ["1", "2", "+"]

static VALUE match_values_at(int argc, VALUE *argv, VALUE match) { VALUE result; int i; match_check(match result = rb_ary_new2(argc for (i=0; i<argc; i++) { if (FIXNUM_P(argv[i])) { rb_ary_push(result, rb_reg_nth_match(FIX2INT(argv[i]), match) } else { int num = namev_to_backref_number(RMATCH_REGS(match), RMATCH(match)->regexp, argv[i] if (num >= 0) { rb_ary_push(result, rb_reg_nth_match(num, match) } else { match_ary_aref(match, argv[i], result } } } return result; }