summaryrefslogtreecommitdiff
path: root/re.c
diff options
context:
space:
mode:
authorkosako <kosako@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-03-22 15:03:40 +0000
committerkosako <kosako@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-03-22 15:03:40 +0000
commit0fa1086760eb0a5964789eb619769764107458ca (patch)
treed0f568425d4c6cc55881ae6c9d40375350bf1548 /re.c
parenta350e9c6e2935b2c2d358b94327a0c7028668c11 (diff)
add back reference by name in replace string
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10046 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 're.c')
-rw-r--r--re.c56
1 files changed, 45 insertions, 11 deletions
diff --git a/re.c b/re.c
index 9570a775e1..e2b27bdbd6 100644
--- a/re.c
+++ b/re.c
@@ -1158,6 +1158,22 @@ match_captures(VALUE match)
return match_array(match, 1);
}
+static int
+name_to_backref_number(struct re_registers *regs, VALUE regexp, char* name, char* name_end)
+{
+ int num;
+
+ num = onig_name_to_backref_number(RREGEXP(regexp)->ptr,
+ (unsigned char* )name, (unsigned char* )name_end, regs);
+ if (num >= 1) {
+ return num;
+ }
+ else {
+ VALUE s = rb_str_new(name, (long )(name_end - name));
+ rb_raise(rb_eRuntimeError, "undefined group name reference: %s",
+ StringValuePtr(s));
+ }
+}
/*
* call-seq:
@@ -1192,7 +1208,7 @@ match_aref(int argc, VALUE *argv, VALUE match)
}
}
else {
- char *p, *end;
+ char *p;
int num;
switch (TYPE(idx)) {
@@ -1204,15 +1220,9 @@ match_aref(int argc, VALUE *argv, VALUE match)
p = StringValuePtr(idx);
name_to_backref:
- end = p + strlen(p);
- num = onig_name_to_backref_number(RREGEXP(RMATCH(match)->regexp)->ptr,
- (unsigned char* )p, (unsigned char* )end, RMATCH(match)->regs);
- if (num >= 1) {
- return rb_reg_nth_match(num, match);
- }
- else {
- rb_raise(rb_eArgError, "undefined group name reference: %s", p);
- }
+ num = name_to_backref_number(RMATCH(match)->regs,
+ RMATCH(match)->regexp, p, p + strlen(p));
+ return rb_reg_nth_match(num, match);
break;
default:
@@ -2013,7 +2023,7 @@ rb_reg_init_copy(VALUE copy, VALUE re)
}
VALUE
-rb_reg_regsub(VALUE str, VALUE src, struct re_registers *regs)
+rb_reg_regsub(VALUE str, VALUE src, struct re_registers *regs, VALUE regexp)
{
VALUE val = 0;
char *p, *s, *e;
@@ -2049,6 +2059,30 @@ rb_reg_regsub(VALUE str, VALUE src, struct re_registers *regs)
case '5': case '6': case '7': case '8': case '9':
no = uc - '0';
break;
+
+ case 'k':
+ if (s < e && *s == '<') {
+ char *name, *name_end;
+
+ name_end = name = s + 1;
+ while (name_end < e) {
+ if (*name_end == '>') break;
+ uc = (unsigned char)*name_end;
+ name_end += mbclen(uc);
+ }
+ if (name_end < e) {
+ no = name_to_backref_number(regs, regexp, name, name_end);
+ p = s = name_end + 1;
+ break;
+ }
+ else {
+ rb_raise(rb_eRuntimeError, "invalid group name reference format");
+ }
+ }
+
+ rb_str_buf_cat(val, s-2, 2);
+ continue;
+
case '&':
no = 0;
break;