} else if (c == '`') {
type = NJS_SUBST_PRECEDING;
+ } else if (c == '&') {
+ type = 0;
+
} else if (c == '\'') {
type = NJS_SUBST_FOLLOWING;
njs_string_replace_substitute(njs_vm_t *vm, njs_string_replace_t *r,
int *captures)
{
- uint32_t i, n, last, index;
+ int *capture;
+ uint32_t i, n, last;
const u_char *end;
njs_string_subst_t *s;
njs_string_replace_part_t *part, *subject;
- index = 0;
+ capture = NULL;
last = r->substitutions->items;
end = r->part[0].start + r->part[0].size;
break;
/*
- * "$n" substitutions.
- * "$&" is the same as "$0", the "$0" however is not supported.
+ * "$n" and "$&" substitutions.
*/
default:
if (captures[n] == captures[n + 1]) {
/* Empty match. */
- if (captures[n - 1] == captures[n]) {
+ if (n > 0 && captures[n - 1] == captures[n]) {
/*
* Consecutive empty matches as in
break;
}
- index = n;
+ capture = &captures[n];
continue;
}
- if (index != 0) {
+ if (capture != NULL) {
/*
* Inserting a single character after a series of
*/
if (part->start < end) {
- part->start = r->part[0].start + captures[index];
+ part->start = r->part[0].start + *capture;
part->size = nxt_utf8_next(part->start, end) - part->start;
} else {
part->size = 0;
}
- index = 0;
+ capture = NULL;
break;
}
part++;
}
- if (index != 0) {
- part->start = r->part[0].start + captures[index];
+ if (capture != NULL) {
+ part->start = r->part[0].start + *capture;
if (part->start < end) {
part->size = nxt_utf8_next(part->start, end) - part->start;
{ nxt_string("'abc'.replace(/(a*)/g, function v0() {return '124'})"),
nxt_string("124124b124c124") },
- { nxt_string("typeof '0'.replace(/^/g, '$0')"),
- nxt_string("string") },
+ { nxt_string("'abc'.replace(/b/g, '$0')"),
+ nxt_string("a$0c") },
{ nxt_string("typeof String.bytesFrom(Array(15).fill(0xE3)).replace(/^/g, 1)"),
nxt_string("string") },
- { nxt_string("typeof '0'.replace(/^/g, '$&')"),
- nxt_string("string") },
+#if 0 /* FIXME: PCRE limitation */
+ { nxt_string("'abc'.replace(/^/g, '|$&|')"),
+ nxt_string("||abc") },
+#endif
+
+ { nxt_string("'abc'.replace(/b/g, '|$&|')"),
+ nxt_string("a|b|c") },
+
+ { nxt_string("'ABC'.replace(/((A)B)/g, '($1|$&|$2)')"),
+ nxt_string("(AB|AB|A)C") },
{ nxt_string("/]/"),
nxt_string("/\\]/") },