diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-09-22 06:14:27 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-09-22 06:14:27 -0700 |
commit | e3d17617a33941fea6c2f365151e93201aaf152d (patch) | |
tree | 67898edda2983dda7283a4a4d42e037dc0b9f384 /regex.c | |
parent | cbe8ab16302c0224c2e90dc0dd28e64e80b3fe2b (diff) | |
download | txr-e3d17617a33941fea6c2f365151e93201aaf152d.tar.gz txr-e3d17617a33941fea6c2f365151e93201aaf152d.tar.bz2 txr-e3d17617a33941fea6c2f365151e93201aaf152d.zip |
Support functional argument in regsub.
* regex.c (regsub): Allow the second argument to be
a function, which is called with str as an argument,
and returns a range which indicates what part of
the string is to be replaced, or else nil.
* txr.1: Documented functional argument of regsub.
Diffstat (limited to 'regex.c')
-rw-r--r-- | regex.c | 64 |
1 files changed, 41 insertions, 23 deletions
@@ -2523,34 +2523,52 @@ val match_regex_right(val str, val regex, val end) val regsub(val regex, val repl, val str) { - list_collect_decl (out, ptail); - val pos = zero; val isfunc = functionp(repl); - do { - cons_bind (find, len, search_regex(str, regex, pos, nil)); - if (!find) { - if (pos == zero) - return str; - ptail = list_collect(ptail, sub_str(str, pos, nil)); - break; + if (functionp(regex)) { + val range = funcall1(regex, str); + + if (!range) + return str; + + { + val rf = from(range); + val rt = to(range); + + return replace_str(str, if3(isfunc, + funcall1(repl, sub_str(str, rf, rt)), + repl), + rf, rt); } - ptail = list_collect(ptail, sub_str(str, pos, find)); - ptail = list_collect(ptail, if3(isfunc, - funcall1(repl, sub_str(str, find, - plus(find, len))), - repl)); - if (len == zero && eql(find, pos)) { - if (lt(pos, length_str(str))) { - ptail = list_collect(ptail, chr_str(str, pos)); - pos = plus(pos, one); + } else { + list_collect_decl (out, ptail); + val pos = zero; + + do { + cons_bind (find, len, search_regex(str, regex, pos, nil)); + if (!find) { + if (pos == zero) + return str; + ptail = list_collect(ptail, sub_str(str, pos, nil)); + break; } - } else { - pos = plus(find, len); - } - } while (lt(pos, length_str(str))); + ptail = list_collect(ptail, sub_str(str, pos, find)); + ptail = list_collect(ptail, if3(isfunc, + funcall1(repl, sub_str(str, find, + plus(find, len))), + repl)); + if (len == zero && eql(find, pos)) { + if (lt(pos, length_str(str))) { + ptail = list_collect(ptail, chr_str(str, pos)); + pos = plus(pos, one); + } + } else { + pos = plus(find, len); + } + } while (lt(pos, length_str(str))); - return cat_str(out, nil); + return cat_str(out, nil); + } } val search_regst(val haystack, val needle_regex, val start_num, val from_end) |