Feature #8343 ยป 0001-make-StringScanner-accept-names-of-named-captures.patch
ext/strscan/strscan.c | ||
---|---|---|
38 | 38 | |
39 | 39 |
/* the regexp register; legal only when MATCHED_P(s) */ |
40 | 40 |
struct re_registers regs; |
41 | ||
42 |
/* regexp used for last scan */ |
|
43 |
VALUE regex; |
|
41 | 44 |
}; |
42 | 45 | |
43 | 46 |
#define MATCHED_P(s) ((s)->flags & FLAG_MATCHED) |
... | ... | |
456 | 459 |
if (S_RESTLEN(p) < 0) { |
457 | 460 |
return Qnil; |
458 | 461 |
} |
462 | ||
463 |
p->regex = regex; |
|
459 | 464 |
re = rb_reg_prepare_re(regex, p->str); |
460 | 465 |
tmpreg = re != RREGEXP(regex)->ptr; |
461 | 466 |
if (!tmpreg) RREGEXP(regex)->usecnt++; |
... | ... | |
976 | 981 |
* Return the n-th subgroup in the most recent match. |
977 | 982 |
* |
978 | 983 |
* s = StringScanner.new("Fri Dec 12 1975 14:39") |
979 |
* s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
|
|
984 |
* s.scan(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /) # -> "Fri Dec 12 "
|
|
980 | 985 |
* s[0] # -> "Fri Dec 12 " |
981 | 986 |
* s[1] # -> "Fri" |
982 | 987 |
* s[2] # -> "Dec" |
983 | 988 |
* s[3] # -> "12" |
989 |
* s[:wday] # -> "Fri" |
|
990 |
* s[:month] # -> "Dec" |
|
991 |
* s[:day] # -> "12" |
|
984 | 992 |
* s.post_match # -> "1975 14:39" |
985 | 993 |
* s.pre_match # -> "" |
986 | 994 |
*/ |
987 | 995 |
static VALUE |
988 | 996 |
strscan_aref(VALUE self, VALUE idx) |
989 | 997 |
{ |
998 |
const char *name, *name_end; |
|
990 | 999 |
struct strscanner *p; |
991 | 1000 |
long i; |
992 | 1001 | |
993 | 1002 |
GET_SCANNER(self, p); |
994 | 1003 |
if (! MATCHED_P(p)) return Qnil; |
995 | 1004 | |
996 |
i = NUM2LONG(idx); |
|
1005 |
switch (TYPE(idx)) { |
|
1006 |
case T_SYMBOL: |
|
1007 |
name = rb_id2name(SYM2ID(idx)); |
|
1008 |
goto name_to_backref; |
|
1009 |
break; |
|
1010 |
case T_STRING: |
|
1011 |
name = StringValuePtr(idx); |
|
1012 |
name_to_backref: |
|
1013 |
name_end = name + strlen(name); |
|
1014 |
i = onig_name_to_backref_number(RREGEXP(p->regex)->ptr, |
|
1015 |
(const unsigned char* )name, (const unsigned char* )name_end, &(p->regs)); |
|
1016 |
break; |
|
1017 |
default: |
|
1018 |
i = NUM2LONG(idx); |
|
1019 |
} |
|
1020 | ||
997 | 1021 |
if (i < 0) |
998 | 1022 |
i += p->regs.num_regs; |
999 | 1023 |
if (i < 0) return Qnil; |
test/strscan/test_stringscanner.rb | ||
---|---|---|
457 | 457 |
assert_equal true, s[2].tainted? |
458 | 458 |
assert_equal true, s[3].tainted? |
459 | 459 |
assert_equal true, s[4].tainted? |
460 | ||
461 |
s = StringScanner.new("foo bar") |
|
462 |
s.scan /(?<a>(\w+)) (?<b>(\w+))/ |
|
463 |
assert_equal 'foo', s[1] |
|
464 |
assert_equal 'bar', s[2] |
|
465 |
assert_equal 'foo', s[:a] |
|
466 |
assert_equal 'bar', s[:b] |
|
467 |
assert_equal nil, s[:c] |
|
468 |
assert_equal 'foo', s['a'] |
|
469 |
assert_equal 'bar', s['b'] |
|
470 |
assert_equal nil, s['c'] |
|
460 | 471 |
end |
461 | 472 | |
462 | 473 |
def test_pre_match |
463 |
- |