Welcome! Log In Create A New Profile

Advanced

[njs] Added support '$&' substitution in String.prototype.replace().

Alexander Borisov
July 17, 2019 11:22AM
details: https://hg.nginx.org/njs/rev/0960f0568b94
branches:
changeset: 1057:0960f0568b94
user: Alexander Borisov <alexander.borisov@nginx.com>
date: Wed Jul 17 14:24:00 2019 +0300
description:
Added support '$&' substitution in String.prototype.replace().

diffstat:

njs/njs_string.c | 25 ++++++++++++++-----------
njs/test/njs_unit_test.c | 16 ++++++++++++----
2 files changed, 26 insertions(+), 15 deletions(-)

diffs (119 lines):

diff -r 377db9ae390d -r 0960f0568b94 njs/njs_string.c
--- a/njs/njs_string.c Wed Jul 17 16:28:30 2019 +0300
+++ b/njs/njs_string.c Wed Jul 17 14:24:00 2019 +0300
@@ -3516,6 +3516,9 @@ skip:
} else if (c == '`') {
type = NJS_SUBST_PRECEDING;

+ } else if (c == '&') {
+ type = 0;
+
} else if (c == '\'') {
type = NJS_SUBST_FOLLOWING;

@@ -3540,12 +3543,13 @@ static njs_ret_t
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;
@@ -3607,15 +3611,14 @@ njs_string_replace_substitute(njs_vm_t *
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
@@ -3626,11 +3629,11 @@ njs_string_replace_substitute(njs_vm_t *
break;
}

- index = n;
+ capture = &captures[n];
continue;
}

- if (index != 0) {
+ if (capture != NULL) {

/*
* Inserting a single character after a series of
@@ -3638,14 +3641,14 @@ njs_string_replace_substitute(njs_vm_t *
*/

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

@@ -3658,8 +3661,8 @@ njs_string_replace_substitute(njs_vm_t *
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;
diff -r 377db9ae390d -r 0960f0568b94 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Wed Jul 17 16:28:30 2019 +0300
+++ b/njs/test/njs_unit_test.c Wed Jul 17 14:24:00 2019 +0300
@@ -5681,14 +5681,22 @@ static njs_unit_test_t njs_test[] =
{ 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("/\\]/") },
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Added support '$&' substitution in String.prototype.replace().

Alexander Borisov 488 July 17, 2019 11:22AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 313
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready