re2 1.18.1 → 1.18.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc +1 -1
- package/README.md +2 -0
- package/lib/accessors.cc +17 -1
- package/lib/addon.cc +3 -2
- package/lib/exec.cc +45 -10
- package/lib/match.cc +9 -6
- package/lib/new.cc +7 -1
- package/lib/replace.cc +23 -5
- package/lib/wrapped_re2.h +4 -2
- package/package.json +1 -1
- package/re2.js +1 -1
- package/tests/test_replace.js +38 -0
package/.prettierrc
CHANGED
package/README.md
CHANGED
|
@@ -352,6 +352,8 @@ console.log('re2_res : ' + re2_res); // prints: re2_res : abc,a,b,c
|
|
|
352
352
|
|
|
353
353
|
## Release history
|
|
354
354
|
|
|
355
|
+
- 1.18.3 *Fixed bug with non-matched groups. Thx, [Dan Setterquist](https://github.com/dset).*
|
|
356
|
+
- 1.18.2 *Reference to the binary module by its full name.*
|
|
355
357
|
- 1.18.1 *Support for Node 16, 18, 20 + Darwin arm64 precompiled binaries.*
|
|
356
358
|
- 1.18.0 *Modified TS bindings, added a type test (thx, [Kenichi Kamiya](https://github.com/kachick) and [Jamie Magee](https://github.com/JamieMagee)).*
|
|
357
359
|
- 1.17.8 *Updated deps, added Node 19 as a pre-compilation target.*
|
package/lib/accessors.cc
CHANGED
|
@@ -39,9 +39,13 @@ NAN_GETTER(WrappedRE2::GetFlags)
|
|
|
39
39
|
auto re2 = Nan::ObjectWrap::Unwrap<WrappedRE2>(info.This());
|
|
40
40
|
|
|
41
41
|
std::string flags;
|
|
42
|
+
if (re2->hasIndices)
|
|
43
|
+
{
|
|
44
|
+
flags = "d";
|
|
45
|
+
}
|
|
42
46
|
if (re2->global)
|
|
43
47
|
{
|
|
44
|
-
flags
|
|
48
|
+
flags += "g";
|
|
45
49
|
}
|
|
46
50
|
if (re2->ignoreCase)
|
|
47
51
|
{
|
|
@@ -135,6 +139,18 @@ NAN_GETTER(WrappedRE2::GetSticky)
|
|
|
135
139
|
info.GetReturnValue().Set(re2->sticky);
|
|
136
140
|
}
|
|
137
141
|
|
|
142
|
+
NAN_GETTER(WrappedRE2::GetHasIndices)
|
|
143
|
+
{
|
|
144
|
+
if (!WrappedRE2::HasInstance(info.This()))
|
|
145
|
+
{
|
|
146
|
+
info.GetReturnValue().SetUndefined();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
auto re2 = Nan::ObjectWrap::Unwrap<WrappedRE2>(info.This());
|
|
151
|
+
info.GetReturnValue().Set(re2->hasIndices);
|
|
152
|
+
}
|
|
153
|
+
|
|
138
154
|
NAN_GETTER(WrappedRE2::GetLastIndex)
|
|
139
155
|
{
|
|
140
156
|
if (!WrappedRE2::HasInstance(info.This()))
|
package/lib/addon.cc
CHANGED
|
@@ -23,9 +23,9 @@ static NAN_METHOD(GetUtf16Length)
|
|
|
23
23
|
info.GetReturnValue().Set(-1);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
static void cleanup(void*
|
|
26
|
+
static void cleanup(void *p)
|
|
27
27
|
{
|
|
28
|
-
v8::Isolate*
|
|
28
|
+
v8::Isolate *isolate = static_cast<v8::Isolate *>(p);
|
|
29
29
|
auto p_tpl = Nan::GetIsolateData<Nan::Persistent<v8::FunctionTemplate>>(isolate);
|
|
30
30
|
delete p_tpl;
|
|
31
31
|
}
|
|
@@ -71,6 +71,7 @@ v8::Local<v8::Function> WrappedRE2::Init()
|
|
|
71
71
|
Nan::SetAccessor(instanceTemplate, Nan::New("dotAll").ToLocalChecked(), GetDotAll);
|
|
72
72
|
Nan::SetAccessor(instanceTemplate, Nan::New("unicode").ToLocalChecked(), GetUnicode);
|
|
73
73
|
Nan::SetAccessor(instanceTemplate, Nan::New("sticky").ToLocalChecked(), GetSticky);
|
|
74
|
+
Nan::SetAccessor(instanceTemplate, Nan::New("hasIndices").ToLocalChecked(), GetHasIndices);
|
|
74
75
|
Nan::SetAccessor(instanceTemplate, Nan::New("lastIndex").ToLocalChecked(), GetLastIndex, SetLastIndex);
|
|
75
76
|
Nan::SetAccessor(instanceTemplate, Nan::New("internalSource").ToLocalChecked(), GetInternalSource);
|
|
76
77
|
|
package/lib/exec.cc
CHANGED
|
@@ -52,8 +52,9 @@ NAN_METHOD(WrappedRE2::Exec)
|
|
|
52
52
|
{
|
|
53
53
|
size_t s = getUtf8CharSize(str.data[lastIndex]);
|
|
54
54
|
lastIndex += s;
|
|
55
|
-
if (s == 4 && n >= 2)
|
|
56
|
-
|
|
55
|
+
if (s == 4 && n >= 2)
|
|
56
|
+
--n; // this utf8 character will take two utf16 characters
|
|
57
|
+
// the decrement above is protected to avoid an overflow of an unsigned integer
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
}
|
|
@@ -74,7 +75,7 @@ NAN_METHOD(WrappedRE2::Exec)
|
|
|
74
75
|
|
|
75
76
|
// form a result
|
|
76
77
|
|
|
77
|
-
auto result = Nan::New<v8::Array>();
|
|
78
|
+
auto result = Nan::New<v8::Array>(), indices = Nan::New<v8::Array>();
|
|
78
79
|
int indexOffset = re2->global || re2->sticky ? re2->lastIndex : 0;
|
|
79
80
|
|
|
80
81
|
if (str.isBuffer)
|
|
@@ -82,13 +83,24 @@ NAN_METHOD(WrappedRE2::Exec)
|
|
|
82
83
|
for (size_t i = 0, n = groups.size(); i < n; ++i)
|
|
83
84
|
{
|
|
84
85
|
const auto &item = groups[i];
|
|
85
|
-
|
|
86
|
+
const auto data = item.data();
|
|
87
|
+
if (data)
|
|
86
88
|
{
|
|
87
|
-
Nan::Set(result, i, Nan::CopyBuffer(
|
|
89
|
+
Nan::Set(result, i, Nan::CopyBuffer(data, item.size()).ToLocalChecked());
|
|
90
|
+
if (re2->hasIndices) {
|
|
91
|
+
auto pair = Nan::New<v8::Array>();
|
|
92
|
+
auto offset = data - str.data;
|
|
93
|
+
Nan::Set(pair, 0, Nan::New<v8::Integer>(static_cast<int>(offset)));
|
|
94
|
+
Nan::Set(pair, 1, Nan::New<v8::Integer>(static_cast<int>(offset + item.size())));
|
|
95
|
+
Nan::Set(indices, i, pair);
|
|
96
|
+
}
|
|
88
97
|
}
|
|
89
98
|
else
|
|
90
99
|
{
|
|
91
100
|
Nan::Set(result, i, Nan::Undefined());
|
|
101
|
+
if (re2->hasIndices) {
|
|
102
|
+
Nan::Set(indices, i, Nan::Undefined());
|
|
103
|
+
}
|
|
92
104
|
}
|
|
93
105
|
}
|
|
94
106
|
Nan::Set(result, Nan::New("index").ToLocalChecked(), Nan::New<v8::Integer>(indexOffset + static_cast<int>(groups[0].data() - str.data)));
|
|
@@ -98,18 +110,35 @@ NAN_METHOD(WrappedRE2::Exec)
|
|
|
98
110
|
for (size_t i = 0, n = groups.size(); i < n; ++i)
|
|
99
111
|
{
|
|
100
112
|
const auto &item = groups[i];
|
|
101
|
-
|
|
113
|
+
const auto data = item.data();
|
|
114
|
+
if (data)
|
|
102
115
|
{
|
|
103
|
-
Nan::Set(result, i, Nan::New(
|
|
116
|
+
Nan::Set(result, i, Nan::New(data, item.size()).ToLocalChecked());
|
|
117
|
+
if (re2->hasIndices) {
|
|
118
|
+
auto pair = Nan::New<v8::Array>();
|
|
119
|
+
auto offset = getUtf16Length(str.data + lastIndex, data);
|
|
120
|
+
auto length = getUtf16Length(data, data + item.size());
|
|
121
|
+
Nan::Set(pair, 0, Nan::New<v8::Integer>(static_cast<int>(offset)));
|
|
122
|
+
Nan::Set(pair, 1, Nan::New<v8::Integer>(static_cast<int>(offset + length)));
|
|
123
|
+
Nan::Set(indices, i, pair);
|
|
124
|
+
}
|
|
104
125
|
}
|
|
105
126
|
else
|
|
106
127
|
{
|
|
107
128
|
Nan::Set(result, i, Nan::Undefined());
|
|
129
|
+
if (re2->hasIndices) {
|
|
130
|
+
Nan::Set(indices, i, Nan::Undefined());
|
|
131
|
+
}
|
|
108
132
|
}
|
|
109
133
|
}
|
|
110
134
|
Nan::Set(result, Nan::New("index").ToLocalChecked(), Nan::New<v8::Integer>(indexOffset + static_cast<int>(getUtf16Length(str.data + lastIndex, groups[0].data()))));
|
|
111
135
|
}
|
|
112
136
|
|
|
137
|
+
if (re2->global || re2->sticky)
|
|
138
|
+
{
|
|
139
|
+
re2->lastIndex += str.isBuffer ? groups[0].data() - str.data + groups[0].size() - lastIndex : getUtf16Length(str.data + lastIndex, groups[0].data() + groups[0].size());
|
|
140
|
+
}
|
|
141
|
+
|
|
113
142
|
Nan::Set(result, Nan::New("input").ToLocalChecked(), info[0]);
|
|
114
143
|
|
|
115
144
|
const auto &groupNames = re2->regexp.CapturingGroupNames();
|
|
@@ -128,15 +157,21 @@ NAN_METHOD(WrappedRE2::Exec)
|
|
|
128
157
|
}
|
|
129
158
|
|
|
130
159
|
Nan::Set(result, Nan::New("groups").ToLocalChecked(), groups);
|
|
160
|
+
|
|
161
|
+
if (re2->hasIndices) {
|
|
162
|
+
Nan::Set(indices, Nan::New("groups").ToLocalChecked(), groups);
|
|
163
|
+
}
|
|
131
164
|
}
|
|
132
165
|
else
|
|
133
166
|
{
|
|
134
167
|
Nan::Set(result, Nan::New("groups").ToLocalChecked(), Nan::Undefined());
|
|
168
|
+
if (re2->hasIndices) {
|
|
169
|
+
Nan::Set(indices, Nan::New("groups").ToLocalChecked(), Nan::Undefined());
|
|
170
|
+
}
|
|
135
171
|
}
|
|
136
172
|
|
|
137
|
-
if (re2->
|
|
138
|
-
|
|
139
|
-
re2->lastIndex += str.isBuffer ? groups[0].data() - str.data + groups[0].size() - lastIndex : getUtf16Length(str.data + lastIndex, groups[0].data() + groups[0].size());
|
|
173
|
+
if (re2->hasIndices) {
|
|
174
|
+
Nan::Set(result, Nan::New("indices").ToLocalChecked(), indices);
|
|
140
175
|
}
|
|
141
176
|
|
|
142
177
|
info.GetReturnValue().Set(result);
|
package/lib/match.cc
CHANGED
|
@@ -61,8 +61,9 @@ NAN_METHOD(WrappedRE2::Match)
|
|
|
61
61
|
{
|
|
62
62
|
size_t s = getUtf8CharSize(a.data[lastIndex]);
|
|
63
63
|
lastIndex += s;
|
|
64
|
-
if (s == 4 && n >= 2)
|
|
65
|
-
|
|
64
|
+
if (s == 4 && n >= 2)
|
|
65
|
+
--n; // this utf8 character will take two utf16 characters
|
|
66
|
+
// the decrement above is protected to avoid an overflow of an unsigned integer
|
|
66
67
|
}
|
|
67
68
|
anchor = RE2::ANCHOR_START;
|
|
68
69
|
}
|
|
@@ -88,9 +89,10 @@ NAN_METHOD(WrappedRE2::Match)
|
|
|
88
89
|
for (size_t i = 0, n = groups.size(); i < n; ++i)
|
|
89
90
|
{
|
|
90
91
|
const auto &item = groups[i];
|
|
91
|
-
|
|
92
|
+
const auto data = item.data();
|
|
93
|
+
if (data)
|
|
92
94
|
{
|
|
93
|
-
Nan::Set(result, i, Nan::CopyBuffer(
|
|
95
|
+
Nan::Set(result, i, Nan::CopyBuffer(data, item.size()).ToLocalChecked());
|
|
94
96
|
}
|
|
95
97
|
}
|
|
96
98
|
if (!re2->global)
|
|
@@ -104,9 +106,10 @@ NAN_METHOD(WrappedRE2::Match)
|
|
|
104
106
|
for (size_t i = 0, n = groups.size(); i < n; ++i)
|
|
105
107
|
{
|
|
106
108
|
const auto &item = groups[i];
|
|
107
|
-
|
|
109
|
+
const auto data = item.data();
|
|
110
|
+
if (data)
|
|
108
111
|
{
|
|
109
|
-
Nan::Set(result, i, Nan::New(
|
|
112
|
+
Nan::Set(result, i, Nan::New(data, item.size()).ToLocalChecked());
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
if (!re2->global)
|
package/lib/new.cc
CHANGED
|
@@ -232,6 +232,7 @@ NAN_METHOD(WrappedRE2::New)
|
|
|
232
232
|
bool dotAll = false;
|
|
233
233
|
bool unicode = false;
|
|
234
234
|
bool sticky = false;
|
|
235
|
+
bool hasIndices = false;
|
|
235
236
|
|
|
236
237
|
auto context = Nan::GetCurrentContext();
|
|
237
238
|
|
|
@@ -272,6 +273,9 @@ NAN_METHOD(WrappedRE2::New)
|
|
|
272
273
|
case 'y':
|
|
273
274
|
sticky = true;
|
|
274
275
|
break;
|
|
276
|
+
case 'd':
|
|
277
|
+
hasIndices = true;
|
|
278
|
+
break;
|
|
275
279
|
}
|
|
276
280
|
}
|
|
277
281
|
size = 0;
|
|
@@ -306,6 +310,7 @@ NAN_METHOD(WrappedRE2::New)
|
|
|
306
310
|
dotAll = bool(flags & v8::RegExp::kDotAll);
|
|
307
311
|
unicode = bool(flags & v8::RegExp::kUnicode);
|
|
308
312
|
sticky = bool(flags & v8::RegExp::kSticky);
|
|
313
|
+
hasIndices = bool(flags & v8::RegExp::kHasIndices);
|
|
309
314
|
}
|
|
310
315
|
else if (info[0]->IsObject() && !info[0]->IsString())
|
|
311
316
|
{
|
|
@@ -332,6 +337,7 @@ NAN_METHOD(WrappedRE2::New)
|
|
|
332
337
|
dotAll = re2->dotAll;
|
|
333
338
|
unicode = true;
|
|
334
339
|
sticky = re2->sticky;
|
|
340
|
+
hasIndices = re2->hasIndices;
|
|
335
341
|
}
|
|
336
342
|
}
|
|
337
343
|
else if (info[0]->IsString())
|
|
@@ -385,7 +391,7 @@ NAN_METHOD(WrappedRE2::New)
|
|
|
385
391
|
options.set_dot_nl(dotAll);
|
|
386
392
|
options.set_log_errors(false); // inappropriate when embedding
|
|
387
393
|
|
|
388
|
-
std::unique_ptr<WrappedRE2> re2(new WrappedRE2(re2::StringPiece(data, size), options, source, global, ignoreCase, multiline, dotAll, sticky));
|
|
394
|
+
std::unique_ptr<WrappedRE2> re2(new WrappedRE2(re2::StringPiece(data, size), options, source, global, ignoreCase, multiline, dotAll, sticky, hasIndices));
|
|
389
395
|
if (!re2->regexp.ok())
|
|
390
396
|
{
|
|
391
397
|
return Nan::ThrowSyntaxError(re2->regexp.error().c_str());
|
package/lib/replace.cc
CHANGED
|
@@ -228,7 +228,8 @@ static Nan::Maybe<std::string> replace(WrappedRE2 *re2, const StrVal &replacee,
|
|
|
228
228
|
{
|
|
229
229
|
size_t s = getUtf8CharSize(data[lastIndex]);
|
|
230
230
|
lastIndex += s;
|
|
231
|
-
if (s == 4 && n >= 2)
|
|
231
|
+
if (s == 4 && n >= 2)
|
|
232
|
+
{
|
|
232
233
|
--n; // this utf8 character will take two utf16 characters
|
|
233
234
|
}
|
|
234
235
|
// the decrement above is protected to avoid an overflow of an unsigned integer
|
|
@@ -299,7 +300,7 @@ static Nan::Maybe<std::string> replace(WrappedRE2 *re2, const StrVal &replacee,
|
|
|
299
300
|
|
|
300
301
|
inline Nan::Maybe<std::string> replace(const Nan::Callback *replacer, const std::vector<re2::StringPiece> &groups, const re2::StringPiece &str, const v8::Local<v8::Value> &input, bool useBuffers, const std::map<std::string, int> &namedGroups)
|
|
301
302
|
{
|
|
302
|
-
std::vector<v8::Local<v8::Value
|
|
303
|
+
std::vector<v8::Local<v8::Value>> argv;
|
|
303
304
|
|
|
304
305
|
auto context = Nan::GetCurrentContext();
|
|
305
306
|
|
|
@@ -308,7 +309,15 @@ inline Nan::Maybe<std::string> replace(const Nan::Callback *replacer, const std:
|
|
|
308
309
|
for (size_t i = 0, n = groups.size(); i < n; ++i)
|
|
309
310
|
{
|
|
310
311
|
const auto &item = groups[i];
|
|
311
|
-
|
|
312
|
+
const auto data = item.data();
|
|
313
|
+
if (data)
|
|
314
|
+
{
|
|
315
|
+
argv.push_back(Nan::CopyBuffer(data, item.size()).ToLocalChecked());
|
|
316
|
+
}
|
|
317
|
+
else
|
|
318
|
+
{
|
|
319
|
+
argv.push_back(Nan::Undefined());
|
|
320
|
+
}
|
|
312
321
|
}
|
|
313
322
|
argv.push_back(Nan::New(static_cast<int>(groups[0].data() - str.data())));
|
|
314
323
|
}
|
|
@@ -317,7 +326,15 @@ inline Nan::Maybe<std::string> replace(const Nan::Callback *replacer, const std:
|
|
|
317
326
|
for (size_t i = 0, n = groups.size(); i < n; ++i)
|
|
318
327
|
{
|
|
319
328
|
const auto &item = groups[i];
|
|
320
|
-
|
|
329
|
+
const auto data = item.data();
|
|
330
|
+
if (data)
|
|
331
|
+
{
|
|
332
|
+
argv.push_back(Nan::New(data, item.size()).ToLocalChecked());
|
|
333
|
+
}
|
|
334
|
+
else
|
|
335
|
+
{
|
|
336
|
+
argv.push_back(Nan::Undefined());
|
|
337
|
+
}
|
|
321
338
|
}
|
|
322
339
|
argv.push_back(Nan::New(static_cast<int>(getUtf16Length(str.data(), groups[0].data()))));
|
|
323
340
|
}
|
|
@@ -381,7 +398,8 @@ static Nan::Maybe<std::string> replace(WrappedRE2 *re2, const StrVal &replacee,
|
|
|
381
398
|
{
|
|
382
399
|
size_t s = getUtf8CharSize(data[lastIndex]);
|
|
383
400
|
lastIndex += s;
|
|
384
|
-
if (s == 4 && n >= 2)
|
|
401
|
+
if (s == 4 && n >= 2)
|
|
402
|
+
{
|
|
385
403
|
--n; // this utf8 character will take two utf16 characters
|
|
386
404
|
}
|
|
387
405
|
// the decrement above is protected to avoid an overflow of an unsigned integer
|
package/lib/wrapped_re2.h
CHANGED
|
@@ -11,8 +11,8 @@ class WrappedRE2 : public Nan::ObjectWrap
|
|
|
11
11
|
{
|
|
12
12
|
private:
|
|
13
13
|
WrappedRE2(const re2::StringPiece &pattern, const re2::RE2::Options &options, const std::string &src,
|
|
14
|
-
const bool &g, const bool &i, const bool &m, const bool &s, const bool &y) : regexp(pattern, options),
|
|
15
|
-
|
|
14
|
+
const bool &g, const bool &i, const bool &m, const bool &s, const bool &y, const bool &d) : regexp(pattern, options),
|
|
15
|
+
source(src), global(g), ignoreCase(i), multiline(m), dotAll(s), sticky(y), hasIndices(d), lastIndex(0) {}
|
|
16
16
|
|
|
17
17
|
static NAN_METHOD(New);
|
|
18
18
|
static NAN_METHOD(ToString);
|
|
@@ -25,6 +25,7 @@ private:
|
|
|
25
25
|
static NAN_GETTER(GetDotAll);
|
|
26
26
|
static NAN_GETTER(GetUnicode);
|
|
27
27
|
static NAN_GETTER(GetSticky);
|
|
28
|
+
static NAN_GETTER(GetHasIndices);
|
|
28
29
|
static NAN_GETTER(GetLastIndex);
|
|
29
30
|
static NAN_SETTER(SetLastIndex);
|
|
30
31
|
static NAN_GETTER(GetInternalSource);
|
|
@@ -70,6 +71,7 @@ public:
|
|
|
70
71
|
bool multiline;
|
|
71
72
|
bool dotAll;
|
|
72
73
|
bool sticky;
|
|
74
|
+
bool hasIndices;
|
|
73
75
|
size_t lastIndex;
|
|
74
76
|
};
|
|
75
77
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "re2",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.3",
|
|
4
4
|
"description": "Bindings for RE2: fast, safe alternative to backtracking regular expression engines.",
|
|
5
5
|
"homepage": "https://github.com/uhop/node-re2",
|
|
6
6
|
"bugs": "https://github.com/uhop/node-re2/issues",
|
package/re2.js
CHANGED
package/tests/test_replace.js
CHANGED
|
@@ -280,5 +280,43 @@ unit.add(module, [
|
|
|
280
280
|
|
|
281
281
|
eval(t.TEST("re2.replace('ABCDEFABCDEF', '!') === '!!!!!FABCDEF'"));
|
|
282
282
|
eval(t.TEST('re2.lastIndex === 0'));
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
// Non-matches
|
|
286
|
+
|
|
287
|
+
function test_ReplaceOneNonMatch(t) {
|
|
288
|
+
'use strict';
|
|
289
|
+
|
|
290
|
+
function replacer(match, capture, offset, string) {
|
|
291
|
+
t.test(typeof offset == 'number');
|
|
292
|
+
t.test(typeof match == 'string');
|
|
293
|
+
t.test(typeof string == 'string');
|
|
294
|
+
t.test(typeof capture == 'undefined');
|
|
295
|
+
t.test(offset === 0);
|
|
296
|
+
t.test(string === 'hello ');
|
|
297
|
+
return '';
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
var re = new RE2(/hello (world)?/);
|
|
301
|
+
re.replace('hello ', replacer);
|
|
302
|
+
},
|
|
303
|
+
function test_ReplaceTwoNonMatches(t) {
|
|
304
|
+
'use strict';
|
|
305
|
+
|
|
306
|
+
function replacer(match, capture1, capture2, offset, string) {
|
|
307
|
+
t.test(typeof offset == 'number');
|
|
308
|
+
t.test(typeof match == 'string');
|
|
309
|
+
t.test(typeof string == 'string');
|
|
310
|
+
t.test(typeof capture1 == 'undefined');
|
|
311
|
+
t.test(typeof capture2 == 'undefined');
|
|
312
|
+
t.test(offset === 1);
|
|
313
|
+
t.test(match === 'b & y');
|
|
314
|
+
t.test(string === 'ab & yz');
|
|
315
|
+
return '';
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
var re = new RE2(/b(1)? & (2)?y/);
|
|
319
|
+
var result = re.replace('ab & yz', replacer);
|
|
320
|
+
eval(t.TEST("result === 'az'"));
|
|
283
321
|
}
|
|
284
322
|
]);
|