re2 1.18.3 → 1.19.1
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/README.md +3 -0
- package/lib/exec.cc +17 -5
- package/lib/match.cc +60 -1
- package/package.json +4 -4
- package/tests/test_exec.js +113 -9
- package/tests/test_match.js +129 -94
- package/tests/test_replace.js +24 -8
package/README.md
CHANGED
|
@@ -58,6 +58,7 @@ Supported properties:
|
|
|
58
58
|
* [`re2.unicode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode)
|
|
59
59
|
* `RE2` engine always works in the Unicode mode. See details below.
|
|
60
60
|
* [`re2.sticky`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky)
|
|
61
|
+
* *Since 1.19.0*: [`re2.hasIndices`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/hasIndices)
|
|
61
62
|
* [`re2.source`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source)
|
|
62
63
|
* [`re2.flags`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags)
|
|
63
64
|
|
|
@@ -352,6 +353,8 @@ console.log('re2_res : ' + re2_res); // prints: re2_res : abc,a,b,c
|
|
|
352
353
|
|
|
353
354
|
## Release history
|
|
354
355
|
|
|
356
|
+
- 1.19.1 *Bugfix: indices for the `d` flag when `lastIndex` is non zero. Bugfix: the match result. Thx, [teebu](https://github.com/teebu).*
|
|
357
|
+
- 1.19.0 *Added `hasIndices` AKA the `d` flag. Thx, [teebu](https://github.com/teebu).*
|
|
355
358
|
- 1.18.3 *Fixed bug with non-matched groups. Thx, [Dan Setterquist](https://github.com/dset).*
|
|
356
359
|
- 1.18.2 *Reference to the binary module by its full name.*
|
|
357
360
|
- 1.18.1 *Support for Node 16, 18, 20 + Darwin arm64 precompiled binaries.*
|
package/lib/exec.cc
CHANGED
|
@@ -90,8 +90,8 @@ NAN_METHOD(WrappedRE2::Exec)
|
|
|
90
90
|
if (re2->hasIndices) {
|
|
91
91
|
auto pair = Nan::New<v8::Array>();
|
|
92
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())));
|
|
93
|
+
Nan::Set(pair, 0, Nan::New<v8::Integer>(indexOffset + static_cast<int>(offset)));
|
|
94
|
+
Nan::Set(pair, 1, Nan::New<v8::Integer>(indexOffset + static_cast<int>(offset + item.size())));
|
|
95
95
|
Nan::Set(indices, i, pair);
|
|
96
96
|
}
|
|
97
97
|
}
|
|
@@ -118,8 +118,8 @@ NAN_METHOD(WrappedRE2::Exec)
|
|
|
118
118
|
auto pair = Nan::New<v8::Array>();
|
|
119
119
|
auto offset = getUtf16Length(str.data + lastIndex, data);
|
|
120
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)));
|
|
121
|
+
Nan::Set(pair, 0, Nan::New<v8::Integer>(indexOffset + static_cast<int>(offset)));
|
|
122
|
+
Nan::Set(pair, 1, Nan::New<v8::Integer>(indexOffset + static_cast<int>(offset + length)));
|
|
123
123
|
Nan::Set(indices, i, pair);
|
|
124
124
|
}
|
|
125
125
|
}
|
|
@@ -159,7 +159,19 @@ NAN_METHOD(WrappedRE2::Exec)
|
|
|
159
159
|
Nan::Set(result, Nan::New("groups").ToLocalChecked(), groups);
|
|
160
160
|
|
|
161
161
|
if (re2->hasIndices) {
|
|
162
|
-
|
|
162
|
+
auto indexGroups = Nan::New<v8::Object>();
|
|
163
|
+
Nan::SetPrototype(indexGroups, Nan::Null());
|
|
164
|
+
|
|
165
|
+
for (auto group : groupNames)
|
|
166
|
+
{
|
|
167
|
+
auto value = Nan::Get(indices, group.first);
|
|
168
|
+
if (!value.IsEmpty())
|
|
169
|
+
{
|
|
170
|
+
Nan::Set(indexGroups, Nan::New(group.second).ToLocalChecked(), value.ToLocalChecked());
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
Nan::Set(indices, Nan::New("groups").ToLocalChecked(), indexGroups);
|
|
163
175
|
}
|
|
164
176
|
}
|
|
165
177
|
else
|
package/lib/match.cc
CHANGED
|
@@ -82,7 +82,7 @@ NAN_METHOD(WrappedRE2::Match)
|
|
|
82
82
|
|
|
83
83
|
// form a result
|
|
84
84
|
|
|
85
|
-
auto result = Nan::New<v8::Array>();
|
|
85
|
+
auto result = Nan::New<v8::Array>(), indices = Nan::New<v8::Array>();
|
|
86
86
|
|
|
87
87
|
if (a.isBuffer)
|
|
88
88
|
{
|
|
@@ -93,6 +93,23 @@ NAN_METHOD(WrappedRE2::Match)
|
|
|
93
93
|
if (data)
|
|
94
94
|
{
|
|
95
95
|
Nan::Set(result, i, Nan::CopyBuffer(data, item.size()).ToLocalChecked());
|
|
96
|
+
if (!re2->global && re2->hasIndices)
|
|
97
|
+
{
|
|
98
|
+
auto pair = Nan::New<v8::Array>();
|
|
99
|
+
auto offset = getUtf16Length(a.data + lastIndex, data);
|
|
100
|
+
auto length = getUtf16Length(data, data + item.size());
|
|
101
|
+
Nan::Set(pair, 0, Nan::New<v8::Integer>(static_cast<int>(offset)));
|
|
102
|
+
Nan::Set(pair, 1, Nan::New<v8::Integer>(static_cast<int>(offset + length)));
|
|
103
|
+
Nan::Set(indices, i, pair);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else
|
|
107
|
+
{
|
|
108
|
+
Nan::Set(result, i, Nan::Undefined());
|
|
109
|
+
if (!re2->global && re2->hasIndices)
|
|
110
|
+
{
|
|
111
|
+
Nan::Set(indices, i, Nan::Undefined());
|
|
112
|
+
}
|
|
96
113
|
}
|
|
97
114
|
}
|
|
98
115
|
if (!re2->global)
|
|
@@ -110,6 +127,23 @@ NAN_METHOD(WrappedRE2::Match)
|
|
|
110
127
|
if (data)
|
|
111
128
|
{
|
|
112
129
|
Nan::Set(result, i, Nan::New(data, item.size()).ToLocalChecked());
|
|
130
|
+
if (!re2->global && re2->hasIndices)
|
|
131
|
+
{
|
|
132
|
+
auto pair = Nan::New<v8::Array>();
|
|
133
|
+
auto offset = getUtf16Length(a.data + lastIndex, data);
|
|
134
|
+
auto length = getUtf16Length(data, data + item.size());
|
|
135
|
+
Nan::Set(pair, 0, Nan::New<v8::Integer>(static_cast<int>(offset)));
|
|
136
|
+
Nan::Set(pair, 1, Nan::New<v8::Integer>(static_cast<int>(offset + length)));
|
|
137
|
+
Nan::Set(indices, i, pair);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else
|
|
141
|
+
{
|
|
142
|
+
Nan::Set(result, i, Nan::Undefined());
|
|
143
|
+
if (!re2->global && re2->hasIndices)
|
|
144
|
+
{
|
|
145
|
+
Nan::Set(indices, i, Nan::Undefined());
|
|
146
|
+
}
|
|
113
147
|
}
|
|
114
148
|
}
|
|
115
149
|
if (!re2->global)
|
|
@@ -146,10 +180,35 @@ NAN_METHOD(WrappedRE2::Match)
|
|
|
146
180
|
}
|
|
147
181
|
|
|
148
182
|
Nan::Set(result, Nan::New("groups").ToLocalChecked(), groups);
|
|
183
|
+
|
|
184
|
+
if (re2->hasIndices)
|
|
185
|
+
{
|
|
186
|
+
auto indexGroups = Nan::New<v8::Object>();
|
|
187
|
+
Nan::SetPrototype(indexGroups, Nan::Null());
|
|
188
|
+
|
|
189
|
+
for (auto group : groupNames)
|
|
190
|
+
{
|
|
191
|
+
auto value = Nan::Get(indices, group.first);
|
|
192
|
+
if (!value.IsEmpty())
|
|
193
|
+
{
|
|
194
|
+
Nan::Set(indexGroups, Nan::New(group.second).ToLocalChecked(), value.ToLocalChecked());
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
Nan::Set(indices, Nan::New("groups").ToLocalChecked(), indexGroups);
|
|
199
|
+
}
|
|
149
200
|
}
|
|
150
201
|
else
|
|
151
202
|
{
|
|
152
203
|
Nan::Set(result, Nan::New("groups").ToLocalChecked(), Nan::Undefined());
|
|
204
|
+
if (re2->hasIndices)
|
|
205
|
+
{
|
|
206
|
+
Nan::Set(indices, Nan::New("groups").ToLocalChecked(), Nan::Undefined());
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (re2->hasIndices)
|
|
210
|
+
{
|
|
211
|
+
Nan::Set(result, Nan::New("indices").ToLocalChecked(), indices);
|
|
153
212
|
}
|
|
154
213
|
}
|
|
155
214
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "re2",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.1",
|
|
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",
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"install-artifact-from-github": "^1.3.3",
|
|
15
15
|
"nan": "^2.17.0",
|
|
16
|
-
"node-gyp": "^9.
|
|
16
|
+
"node-gyp": "^9.4.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@types/node": "^20.
|
|
19
|
+
"@types/node": "^20.3.1",
|
|
20
20
|
"heya-unit": "^0.3.0",
|
|
21
|
-
"typescript": "^5.
|
|
21
|
+
"typescript": "^5.1.3"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
24
|
"test": "node tests/tests.js",
|
package/tests/test_exec.js
CHANGED
|
@@ -21,9 +21,13 @@ unit.add(module, [
|
|
|
21
21
|
|
|
22
22
|
var result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog');
|
|
23
23
|
|
|
24
|
-
eval(
|
|
24
|
+
eval(
|
|
25
|
+
t.TEST("t.unify(result, ['Quick Brown Fox Jumps', 'Brown', 'Jumps'])")
|
|
26
|
+
);
|
|
25
27
|
eval(t.TEST('result.index === 4'));
|
|
26
|
-
eval(
|
|
28
|
+
eval(
|
|
29
|
+
t.TEST("result.input === 'The Quick Brown Fox Jumps Over The Lazy Dog'")
|
|
30
|
+
);
|
|
27
31
|
eval(t.TEST('re.lastIndex === 25'));
|
|
28
32
|
},
|
|
29
33
|
function test_execSucc(t) {
|
|
@@ -148,12 +152,20 @@ unit.add(module, [
|
|
|
148
152
|
|
|
149
153
|
var result = re.exec('Каждый Охотник Желает Знать Где Сидит Фазан');
|
|
150
154
|
|
|
151
|
-
eval(
|
|
155
|
+
eval(
|
|
156
|
+
t.TEST("t.unify(result, ['Охотник Желает Знать Где', 'Желает', 'Где'])")
|
|
157
|
+
);
|
|
152
158
|
eval(t.TEST('result.index === 7'));
|
|
153
|
-
eval(
|
|
159
|
+
eval(
|
|
160
|
+
t.TEST("result.input === 'Каждый Охотник Желает Знать Где Сидит Фазан'")
|
|
161
|
+
);
|
|
154
162
|
eval(t.TEST('re.lastIndex === 31'));
|
|
155
163
|
|
|
156
|
-
eval(
|
|
164
|
+
eval(
|
|
165
|
+
t.TEST(
|
|
166
|
+
"result.input.substr(result.index) === 'Охотник Желает Знать Где Сидит Фазан'"
|
|
167
|
+
)
|
|
168
|
+
);
|
|
157
169
|
eval(t.TEST("result.input.substr(re.lastIndex) === ' Сидит Фазан'"));
|
|
158
170
|
},
|
|
159
171
|
function test_execUnicodeSubsequent(t) {
|
|
@@ -248,11 +260,21 @@ unit.add(module, [
|
|
|
248
260
|
|
|
249
261
|
eval(t.TEST('result.index === 13'));
|
|
250
262
|
eval(t.TEST('result.input instanceof Buffer'));
|
|
251
|
-
eval(
|
|
263
|
+
eval(
|
|
264
|
+
t.TEST(
|
|
265
|
+
"result.input.toString() === 'Каждый Охотник Желает Знать Где Сидит Фазан'"
|
|
266
|
+
)
|
|
267
|
+
);
|
|
252
268
|
eval(t.TEST('re.lastIndex === 58'));
|
|
253
269
|
|
|
254
|
-
eval(
|
|
255
|
-
|
|
270
|
+
eval(
|
|
271
|
+
t.TEST(
|
|
272
|
+
"result.input.toString('utf8', result.index) === 'Охотник Желает Знать Где Сидит Фазан'"
|
|
273
|
+
)
|
|
274
|
+
);
|
|
275
|
+
eval(
|
|
276
|
+
t.TEST("result.input.toString('utf8', re.lastIndex) === ' Сидит Фазан'")
|
|
277
|
+
);
|
|
256
278
|
},
|
|
257
279
|
|
|
258
280
|
// Sticky tests
|
|
@@ -317,7 +339,9 @@ xy2 (at start of line)
|
|
|
317
339
|
eval(t.TEST("result[0] === 'xy'"));
|
|
318
340
|
eval(t.TEST('result.index > 3'));
|
|
319
341
|
eval(t.TEST('result.index < pattern.length - 4'));
|
|
320
|
-
eval(
|
|
342
|
+
eval(
|
|
343
|
+
t.TEST('result[0] === pattern.substr(result.index, result[0].length)')
|
|
344
|
+
);
|
|
321
345
|
},
|
|
322
346
|
|
|
323
347
|
// dotAll tests
|
|
@@ -332,5 +356,85 @@ xy2 (at start of line)
|
|
|
332
356
|
eval(t.TEST("new RE2('a.c', 's').test('abc')"));
|
|
333
357
|
eval(t.TEST("new RE2(/a.c/s).test('a c')"));
|
|
334
358
|
eval(t.TEST("new RE2(/a.c/s).test('a\\nc')"));
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
// hasIndices tests
|
|
362
|
+
|
|
363
|
+
function test_execHasIndices(t) {
|
|
364
|
+
'use strict';
|
|
365
|
+
|
|
366
|
+
eval(t.TEST("!new RE2('1').hasIndices"));
|
|
367
|
+
eval(t.TEST('!new RE2(/1/).hasIndices'));
|
|
368
|
+
|
|
369
|
+
var re = new RE2('(aa)(?<b>b)?(?<c>ccc)', 'd');
|
|
370
|
+
|
|
371
|
+
eval(t.TEST('re.hasIndices'));
|
|
372
|
+
|
|
373
|
+
var result = re.exec('1aabccc2');
|
|
374
|
+
|
|
375
|
+
eval(t.TEST('result.length === 4'));
|
|
376
|
+
eval(t.TEST("result.input === '1aabccc2'"));
|
|
377
|
+
eval(t.TEST('result.index === 1'));
|
|
378
|
+
eval(t.TEST('Object.keys(result.groups).length === 2'));
|
|
379
|
+
eval(t.TEST("result.groups.b === 'b'"));
|
|
380
|
+
eval(t.TEST("result.groups.c === 'ccc'"));
|
|
381
|
+
eval(t.TEST("result[0] === 'aabccc'"));
|
|
382
|
+
eval(t.TEST("result[1] === 'aa'"));
|
|
383
|
+
eval(t.TEST("result[2] === 'b'"));
|
|
384
|
+
eval(t.TEST("result[3] === 'ccc'"));
|
|
385
|
+
eval(t.TEST('result.indices.length === 4'));
|
|
386
|
+
eval(t.TEST('t.unify(result.indices, [[1, 7], [1, 3], [3, 4], [4, 7]])'));
|
|
387
|
+
eval(t.TEST('Object.keys(result.indices.groups).length === 2'));
|
|
388
|
+
eval(t.TEST('t.unify(result.indices.groups.b, [3, 4])'));
|
|
389
|
+
eval(t.TEST('t.unify(result.indices.groups.c, [4, 7])'));
|
|
390
|
+
|
|
391
|
+
result = re.exec('1aaccc2');
|
|
392
|
+
|
|
393
|
+
eval(t.TEST('result.length === 4'));
|
|
394
|
+
eval(t.TEST("result.input === '1aaccc2'"));
|
|
395
|
+
eval(t.TEST('result.index === 1'));
|
|
396
|
+
eval(t.TEST('Object.keys(result.groups).length === 2'));
|
|
397
|
+
eval(t.TEST('result.groups.b === undefined'));
|
|
398
|
+
eval(t.TEST("result.groups.c === 'ccc'"));
|
|
399
|
+
eval(t.TEST("result[0] === 'aaccc'"));
|
|
400
|
+
eval(t.TEST("result[1] === 'aa'"));
|
|
401
|
+
eval(t.TEST('result[2] === undefined'));
|
|
402
|
+
eval(t.TEST("result[3] === 'ccc'"));
|
|
403
|
+
eval(t.TEST('result.indices.length === 4'));
|
|
404
|
+
eval(
|
|
405
|
+
t.TEST('t.unify(result.indices, [[1, 6], [1, 3], undefined, [3, 6]])')
|
|
406
|
+
);
|
|
407
|
+
eval(t.TEST('Object.keys(result.indices.groups).length === 2'));
|
|
408
|
+
eval(t.TEST('t.unify(result.indices.groups.b, undefined)'));
|
|
409
|
+
eval(t.TEST('t.unify(result.indices.groups.c, [3, 6])'));
|
|
410
|
+
|
|
411
|
+
try {
|
|
412
|
+
re = new RE2(new RegExp('1', 'd'));
|
|
413
|
+
eval(t.TEST('re.hasIndices'));
|
|
414
|
+
} catch (e) {
|
|
415
|
+
// squelch
|
|
416
|
+
}
|
|
417
|
+
},
|
|
418
|
+
|
|
419
|
+
function test_hasIndexLastIndex(t) {
|
|
420
|
+
'use strict';
|
|
421
|
+
|
|
422
|
+
const re2 = new RE2('a', 'dg');
|
|
423
|
+
|
|
424
|
+
eval(t.TEST('re2.lastIndex === 0'));
|
|
425
|
+
|
|
426
|
+
let result = re2.exec('abca');
|
|
427
|
+
eval(t.TEST('re2.lastIndex === 1'));
|
|
428
|
+
eval(t.TEST('result.index === 0'));
|
|
429
|
+
eval(t.TEST('t.unify(result.indices, [[0, 1]])'));
|
|
430
|
+
|
|
431
|
+
result = re2.exec('abca');
|
|
432
|
+
eval(t.TEST('re2.lastIndex === 4'));
|
|
433
|
+
eval(t.TEST('result.index === 3'));
|
|
434
|
+
eval(t.TEST('t.unify(result.indices, [[3, 4]])'));
|
|
435
|
+
|
|
436
|
+
result = re2.exec('abca');
|
|
437
|
+
eval(t.TEST('re2.lastIndex === 0'));
|
|
438
|
+
eval(t.TEST('result === null'));
|
|
335
439
|
}
|
|
336
440
|
]);
|
package/tests/test_match.js
CHANGED
|
@@ -1,137 +1,172 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var unit = require("heya-unit");
|
|
5
|
-
var RE2 = require("../re2");
|
|
1
|
+
'use strict';
|
|
6
2
|
|
|
3
|
+
var unit = require('heya-unit');
|
|
4
|
+
var RE2 = require('../re2');
|
|
7
5
|
|
|
8
6
|
// tests
|
|
9
7
|
|
|
10
8
|
unit.add(module, [
|
|
9
|
+
// These tests are copied from MDN:
|
|
10
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match
|
|
11
|
+
|
|
12
|
+
function test_match(t) {
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
var str = 'For more information, see Chapter 3.4.5.1';
|
|
16
|
+
|
|
17
|
+
var re = new RE2(/(chapter \d+(\.\d)*)/i);
|
|
18
|
+
var result = re.match(str);
|
|
19
|
+
|
|
20
|
+
eval(t.TEST('result.input === str'));
|
|
21
|
+
eval(t.TEST('result.index === 26'));
|
|
22
|
+
eval(t.TEST('result.length === 3'));
|
|
23
|
+
eval(t.TEST("result[0] === 'Chapter 3.4.5.1'"));
|
|
24
|
+
eval(t.TEST("result[1] === 'Chapter 3.4.5.1'"));
|
|
25
|
+
eval(t.TEST("result[2] === '.1'"));
|
|
26
|
+
},
|
|
27
|
+
function test_matchGlobal(t) {
|
|
28
|
+
'use strict';
|
|
29
|
+
|
|
30
|
+
var re = new RE2(/[A-E]/gi);
|
|
31
|
+
var result = re.match(
|
|
32
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
eval(
|
|
36
|
+
t.TEST(
|
|
37
|
+
"t.unify(result, ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e'])"
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
},
|
|
41
|
+
function test_matchFail(t) {
|
|
42
|
+
'use strict';
|
|
11
43
|
|
|
12
|
-
|
|
13
|
-
|
|
44
|
+
var re = new RE2('(a+)?(b+)?');
|
|
45
|
+
var result = re.match('aaabb');
|
|
14
46
|
|
|
15
|
-
|
|
16
|
-
|
|
47
|
+
eval(t.TEST("result[1] === 'aaa'"));
|
|
48
|
+
eval(t.TEST("result[2] === 'bb'"));
|
|
17
49
|
|
|
18
|
-
|
|
50
|
+
result = re.match('aaacbb');
|
|
19
51
|
|
|
20
|
-
|
|
21
|
-
|
|
52
|
+
eval(t.TEST("result[1] === 'aaa'"));
|
|
53
|
+
eval(t.TEST('result[2] === undefined'));
|
|
54
|
+
},
|
|
55
|
+
function test_matchInvalid(t) {
|
|
56
|
+
'use strict';
|
|
22
57
|
|
|
23
|
-
|
|
24
|
-
eval(t.TEST("result.index === 26"));
|
|
25
|
-
eval(t.TEST("result.length === 3"));
|
|
26
|
-
eval(t.TEST("result[0] === 'Chapter 3.4.5.1'"));
|
|
27
|
-
eval(t.TEST("result[1] === 'Chapter 3.4.5.1'"));
|
|
28
|
-
eval(t.TEST("result[2] === '.1'"));
|
|
29
|
-
},
|
|
30
|
-
function test_matchGlobal(t) {
|
|
31
|
-
"use strict";
|
|
58
|
+
var re = RE2('');
|
|
32
59
|
|
|
33
|
-
|
|
34
|
-
|
|
60
|
+
try {
|
|
61
|
+
re.match({
|
|
62
|
+
toString() {
|
|
63
|
+
throw 'corner';
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
t.test(false); // shouldn't be here
|
|
67
|
+
} catch (e) {
|
|
68
|
+
eval(t.TEST("e === 'corner'"));
|
|
69
|
+
}
|
|
70
|
+
},
|
|
35
71
|
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
function test_matchFail(t) {
|
|
39
|
-
"use strict";
|
|
72
|
+
// Unicode tests
|
|
40
73
|
|
|
41
|
-
|
|
42
|
-
|
|
74
|
+
function test_matchUnicode(t) {
|
|
75
|
+
'use strict';
|
|
43
76
|
|
|
44
|
-
|
|
45
|
-
eval(t.TEST("result[2] === 'bb'"));
|
|
77
|
+
var str = 'Это ГЛАВА 3.4.5.1';
|
|
46
78
|
|
|
47
|
-
|
|
79
|
+
var re = new RE2(/(глава \d+(\.\d)*)/i);
|
|
80
|
+
var result = re.match(str);
|
|
48
81
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
82
|
+
eval(t.TEST('result.input === str'));
|
|
83
|
+
eval(t.TEST('result.index === 4'));
|
|
84
|
+
eval(t.TEST('result.length === 3'));
|
|
85
|
+
eval(t.TEST("result[0] === 'ГЛАВА 3.4.5.1'"));
|
|
86
|
+
eval(t.TEST("result[1] === 'ГЛАВА 3.4.5.1'"));
|
|
87
|
+
eval(t.TEST("result[2] === '.1'"));
|
|
88
|
+
},
|
|
54
89
|
|
|
55
|
-
|
|
90
|
+
// Buffer tests
|
|
56
91
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
t.test(false); // shouldn't be here
|
|
60
|
-
} catch(e) {
|
|
61
|
-
eval(t.TEST("e === 'corner'"));
|
|
62
|
-
}
|
|
63
|
-
},
|
|
92
|
+
function test_matchBuffer(t) {
|
|
93
|
+
'use strict';
|
|
64
94
|
|
|
65
|
-
|
|
95
|
+
var buf = new Buffer('Это ГЛАВА 3.4.5.1');
|
|
66
96
|
|
|
67
|
-
|
|
68
|
-
|
|
97
|
+
var re = new RE2(/(глава \d+(\.\d)*)/i);
|
|
98
|
+
var result = re.match(buf);
|
|
69
99
|
|
|
70
|
-
|
|
100
|
+
eval(t.TEST('result.input instanceof Buffer'));
|
|
101
|
+
eval(t.TEST('result.length === 3'));
|
|
102
|
+
eval(t.TEST('result[0] instanceof Buffer'));
|
|
103
|
+
eval(t.TEST('result[1] instanceof Buffer'));
|
|
104
|
+
eval(t.TEST('result[2] instanceof Buffer'));
|
|
71
105
|
|
|
72
|
-
|
|
73
|
-
|
|
106
|
+
eval(t.TEST('result.input === buf'));
|
|
107
|
+
eval(t.TEST('result.index === 7'));
|
|
108
|
+
eval(
|
|
109
|
+
t.TEST("result.input.toString('utf8', result.index) === 'ГЛАВА 3.4.5.1'")
|
|
110
|
+
);
|
|
111
|
+
eval(t.TEST("result[0].toString() === 'ГЛАВА 3.4.5.1'"));
|
|
112
|
+
eval(t.TEST("result[1].toString() === 'ГЛАВА 3.4.5.1'"));
|
|
113
|
+
eval(t.TEST("result[2].toString() === '.1'"));
|
|
114
|
+
},
|
|
74
115
|
|
|
75
|
-
|
|
76
|
-
eval(t.TEST("result.index === 4"));
|
|
77
|
-
eval(t.TEST("result.length === 3"));
|
|
78
|
-
eval(t.TEST("result[0] === 'ГЛАВА 3.4.5.1'"));
|
|
79
|
-
eval(t.TEST("result[1] === 'ГЛАВА 3.4.5.1'"));
|
|
80
|
-
eval(t.TEST("result[2] === '.1'"));
|
|
81
|
-
},
|
|
116
|
+
// Sticky tests
|
|
82
117
|
|
|
83
|
-
|
|
118
|
+
function test_matchSticky(t) {
|
|
119
|
+
'use strict';
|
|
84
120
|
|
|
85
|
-
|
|
86
|
-
"use strict";
|
|
121
|
+
var re = new RE2('\\s+', 'y');
|
|
87
122
|
|
|
88
|
-
|
|
123
|
+
eval(t.TEST("re.match('Hello world, how are you?') === null"));
|
|
89
124
|
|
|
90
|
-
|
|
91
|
-
var result = re.match(buf);
|
|
125
|
+
re.lastIndex = 5;
|
|
92
126
|
|
|
93
|
-
|
|
94
|
-
eval(t.TEST("result.length === 3"));
|
|
95
|
-
eval(t.TEST("result[0] instanceof Buffer"));
|
|
96
|
-
eval(t.TEST("result[1] instanceof Buffer"));
|
|
97
|
-
eval(t.TEST("result[2] instanceof Buffer"));
|
|
127
|
+
var result = re.match('Hello world, how are you?');
|
|
98
128
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
eval(t.TEST("result[0].toString() === 'ГЛАВА 3.4.5.1'"));
|
|
103
|
-
eval(t.TEST("result[1].toString() === 'ГЛАВА 3.4.5.1'"));
|
|
104
|
-
eval(t.TEST("result[2].toString() === '.1'"));
|
|
105
|
-
},
|
|
129
|
+
eval(t.TEST("t.unify(result, [' '])"));
|
|
130
|
+
eval(t.TEST('result.index === 5'));
|
|
131
|
+
eval(t.TEST('re.lastIndex === 6'));
|
|
106
132
|
|
|
107
|
-
|
|
133
|
+
var re2 = new RE2('\\s+', 'gy');
|
|
108
134
|
|
|
109
|
-
|
|
110
|
-
"use strict";
|
|
135
|
+
eval(t.TEST("re2.match('Hello world, how are you?') === null"));
|
|
111
136
|
|
|
112
|
-
|
|
137
|
+
re2.lastIndex = 5;
|
|
113
138
|
|
|
114
|
-
|
|
139
|
+
eval(t.TEST("re2.match('Hello world, how are you?') === null"));
|
|
115
140
|
|
|
116
|
-
|
|
141
|
+
var re3 = new RE2(/[A-E]/giy);
|
|
142
|
+
var result3 = re3.match(
|
|
143
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
|
144
|
+
);
|
|
117
145
|
|
|
118
|
-
|
|
146
|
+
eval(t.TEST("t.unify(result3, ['A', 'B', 'C', 'D', 'E'])"));
|
|
147
|
+
},
|
|
119
148
|
|
|
120
|
-
|
|
121
|
-
eval(t.TEST("result.index === 5"));
|
|
122
|
-
eval(t.TEST("re.lastIndex === 6"));
|
|
149
|
+
// hasIndices tests
|
|
123
150
|
|
|
124
|
-
|
|
151
|
+
function test_matchHasIndices(t) {
|
|
152
|
+
'use strict';
|
|
125
153
|
|
|
126
|
-
|
|
154
|
+
const re = new RE2('(aa)(?<b>b)?(?<c>ccc)', 'd'),
|
|
155
|
+
str1 = '1aabccc2',
|
|
156
|
+
str2 = '1aaccc2';
|
|
127
157
|
|
|
128
|
-
|
|
158
|
+
eval(t.TEST("t.unify(str1.match(re), re.exec(str1))"));
|
|
159
|
+
eval(t.TEST("t.unify(str2.match(re), re.exec(str2))"));
|
|
160
|
+
},
|
|
129
161
|
|
|
130
|
-
|
|
162
|
+
function test_matchHasIndicesGlobal(t) {
|
|
163
|
+
'use strict';
|
|
131
164
|
|
|
132
|
-
|
|
133
|
-
|
|
165
|
+
const re = new RE2('(?<zzz>a)', 'dg'),
|
|
166
|
+
result = 'abca'.match(re);
|
|
134
167
|
|
|
135
|
-
|
|
136
|
-
|
|
168
|
+
eval(t.TEST("t.unify(result, ['a', 'a'])"));
|
|
169
|
+
eval(t.TEST("!('indices' in result)"));
|
|
170
|
+
eval(t.TEST("!('groups' in result)"));
|
|
171
|
+
}
|
|
137
172
|
]);
|
package/tests/test_replace.js
CHANGED
|
@@ -13,7 +13,10 @@ unit.add(module, [
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
15
|
var re = new RE2(/apples/gi);
|
|
16
|
-
var result = re.replace(
|
|
16
|
+
var result = re.replace(
|
|
17
|
+
'Apples are round, and apples are juicy.',
|
|
18
|
+
'oranges'
|
|
19
|
+
);
|
|
17
20
|
eval(t.TEST("result === 'oranges are round, and oranges are juicy.'"));
|
|
18
21
|
|
|
19
22
|
re = new RE2(/xmas/i);
|
|
@@ -199,15 +202,24 @@ unit.add(module, [
|
|
|
199
202
|
'use strict';
|
|
200
203
|
|
|
201
204
|
var re = new RE2(/яблоки/gi);
|
|
202
|
-
var result = re.replace(
|
|
205
|
+
var result = re.replace(
|
|
206
|
+
new Buffer('Яблоки красны, яблоки сочны.'),
|
|
207
|
+
'апельсины'
|
|
208
|
+
);
|
|
203
209
|
eval(t.TEST('result instanceof Buffer'));
|
|
204
210
|
eval(t.TEST("result.toString() === 'апельсины красны, апельсины сочны.'"));
|
|
205
211
|
|
|
206
|
-
result = re.replace(
|
|
212
|
+
result = re.replace(
|
|
213
|
+
new Buffer('Яблоки красны, яблоки сочны.'),
|
|
214
|
+
new Buffer('апельсины')
|
|
215
|
+
);
|
|
207
216
|
eval(t.TEST('result instanceof Buffer'));
|
|
208
217
|
eval(t.TEST("result.toString() === 'апельсины красны, апельсины сочны.'"));
|
|
209
218
|
|
|
210
|
-
result = re.replace(
|
|
219
|
+
result = re.replace(
|
|
220
|
+
'Яблоки красны, яблоки сочны.',
|
|
221
|
+
new Buffer('апельсины')
|
|
222
|
+
);
|
|
211
223
|
eval(t.TEST("typeof result == 'string'"));
|
|
212
224
|
eval(t.TEST("result === 'апельсины красны, апельсины сочны.'"));
|
|
213
225
|
},
|
|
@@ -284,7 +296,7 @@ unit.add(module, [
|
|
|
284
296
|
|
|
285
297
|
// Non-matches
|
|
286
298
|
|
|
287
|
-
function
|
|
299
|
+
function test_replaceOneNonMatch(t) {
|
|
288
300
|
'use strict';
|
|
289
301
|
|
|
290
302
|
function replacer(match, capture, offset, string) {
|
|
@@ -300,10 +312,10 @@ unit.add(module, [
|
|
|
300
312
|
var re = new RE2(/hello (world)?/);
|
|
301
313
|
re.replace('hello ', replacer);
|
|
302
314
|
},
|
|
303
|
-
function
|
|
315
|
+
function test_replaceTwoNonMatches(t) {
|
|
304
316
|
'use strict';
|
|
305
317
|
|
|
306
|
-
function replacer(match, capture1, capture2, offset, string) {
|
|
318
|
+
function replacer(match, capture1, capture2, offset, string, groups) {
|
|
307
319
|
t.test(typeof offset == 'number');
|
|
308
320
|
t.test(typeof match == 'string');
|
|
309
321
|
t.test(typeof string == 'string');
|
|
@@ -312,10 +324,14 @@ unit.add(module, [
|
|
|
312
324
|
t.test(offset === 1);
|
|
313
325
|
t.test(match === 'b & y');
|
|
314
326
|
t.test(string === 'ab & yz');
|
|
327
|
+
t.test(typeof groups == 'object');
|
|
328
|
+
t.test(Object.keys(groups).length == 2);
|
|
329
|
+
t.test(groups.a === undefined);
|
|
330
|
+
t.test(groups.b == undefined);
|
|
315
331
|
return '';
|
|
316
332
|
}
|
|
317
333
|
|
|
318
|
-
var re = new RE2(/b(1)? & (2)?y/);
|
|
334
|
+
var re = new RE2(/b(?<a>1)? & (?<b>2)?y/);
|
|
319
335
|
var result = re.replace('ab & yz', replacer);
|
|
320
336
|
eval(t.TEST("result === 'az'"));
|
|
321
337
|
}
|