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
This commit is contained in:
kosako 2006-03-22 15:03:40 +00:00
Родитель a350e9c6e2
Коммит 0fa1086760
5 изменённых файлов: 62 добавлений и 17 удалений

Просмотреть файл

@ -1,3 +1,14 @@
Thu Mar 23 00:01:32 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
* re.c (rb_reg_regsub): add back reference by name \k<name> in
replace string.
* re.h : add regexp argument to rb_reg_regsub().
* string.c (rb_str_sub_bang): ditto.
* string.c (str_gsub): ditto.
Tue Mar 21 22:14:01 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
* re.c (match_alloc): initialize member regexp.

56
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;

2
re.h
Просмотреть файл

@ -31,7 +31,7 @@ struct RMatch {
VALUE rb_reg_regcomp(VALUE);
long rb_reg_search(VALUE, VALUE, long, long);
VALUE rb_reg_regsub(VALUE, VALUE, struct re_registers *);
VALUE rb_reg_regsub(VALUE, VALUE, struct re_registers *, VALUE);
long rb_reg_adjust_startpos(VALUE, VALUE, long, long);
void rb_match_busy(VALUE);
VALUE rb_reg_quote(VALUE);

Просмотреть файл

@ -1848,7 +1848,7 @@ rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
rb_backref_set(match);
}
else {
repl = rb_reg_regsub(repl, str, regs);
repl = rb_reg_regsub(repl, str, regs, pat);
}
if (OBJ_TAINTED(repl)) tainted = 1;
plen = END(0) - BEG(0);
@ -1966,7 +1966,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)
rb_backref_set(match);
}
else {
val = rb_reg_regsub(repl, str, regs);
val = rb_reg_regsub(repl, str, regs, pat);
}
if (OBJ_TAINTED(val)) tainted = 1;
len = (bp - buf) + (beg - offset) + RSTRING(val)->len + 3;

Просмотреть файл

@ -1,14 +1,14 @@
#define RUBY_VERSION "1.9.0"
#define RUBY_RELEASE_DATE "2006-03-21"
#define RUBY_RELEASE_DATE "2006-03-23"
#define RUBY_VERSION_CODE 190
#define RUBY_RELEASE_CODE 20060321
#define RUBY_RELEASE_CODE 20060323
#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 9
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2006
#define RUBY_RELEASE_MONTH 3
#define RUBY_RELEASE_DAY 21
#define RUBY_RELEASE_DAY 23
RUBY_EXTERN const char ruby_version[];
RUBY_EXTERN const char ruby_release_date[];