re2 1.18.3 → 1.19.0
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 +2 -0
- package/lib/exec.cc +13 -1
- package/lib/match.cc +61 -1
- package/package.json +1 -1
- package/tests/test_exec.js +91 -9
- package/tests/test_match.js +119 -95
- 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,7 @@ console.log('re2_res : ' + re2_res); // prints: re2_res : abc,a,b,c
|
|
|
352
353
|
|
|
353
354
|
## Release history
|
|
354
355
|
|
|
356
|
+
- 1.19.0 *Added `hasIndices` AKA the `d` flag. Thx, [teebu](https://github.com/teebu).*
|
|
355
357
|
- 1.18.3 *Fixed bug with non-matched groups. Thx, [Dan Setterquist](https://github.com/dset).*
|
|
356
358
|
- 1.18.2 *Reference to the binary module by its full name.*
|
|
357
359
|
- 1.18.1 *Support for Node 16, 18, 20 + Darwin arm64 precompiled binaries.*
|
package/lib/exec.cc
CHANGED
|
@@ -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,12 +180,38 @@ 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
|
+
}
|
|
153
208
|
}
|
|
154
209
|
}
|
|
155
210
|
|
|
211
|
+
if (re2->hasIndices)
|
|
212
|
+
{
|
|
213
|
+
Nan::Set(result, Nan::New("indices").ToLocalChecked(), indices);
|
|
214
|
+
}
|
|
215
|
+
|
|
156
216
|
info.GetReturnValue().Set(result);
|
|
157
217
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "re2",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.0",
|
|
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/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,63 @@ 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
|
+
}
|
|
335
417
|
}
|
|
336
418
|
]);
|
package/tests/test_match.js
CHANGED
|
@@ -1,137 +1,161 @@
|
|
|
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';
|
|
11
29
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"use strict";
|
|
30
|
+
var re = new RE2(/[A-E]/gi);
|
|
31
|
+
var result = re.match(
|
|
32
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
|
33
|
+
);
|
|
17
34
|
|
|
18
|
-
|
|
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';
|
|
19
43
|
|
|
20
|
-
|
|
21
|
-
|
|
44
|
+
var re = new RE2('(a+)?(b+)?');
|
|
45
|
+
var result = re.match('aaabb');
|
|
22
46
|
|
|
23
|
-
|
|
24
|
-
|
|
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";
|
|
47
|
+
eval(t.TEST("result[1] === 'aaa'"));
|
|
48
|
+
eval(t.TEST("result[2] === 'bb'"));
|
|
32
49
|
|
|
33
|
-
|
|
34
|
-
var result = re.match("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
|
|
50
|
+
result = re.match('aaacbb');
|
|
35
51
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
52
|
+
eval(t.TEST("result[1] === 'aaa'"));
|
|
53
|
+
eval(t.TEST('result[2] === undefined'));
|
|
54
|
+
},
|
|
55
|
+
function test_matchInvalid(t) {
|
|
56
|
+
'use strict';
|
|
40
57
|
|
|
41
|
-
|
|
42
|
-
var result = re.match("aaabb");
|
|
58
|
+
var re = RE2('');
|
|
43
59
|
|
|
44
|
-
|
|
45
|
-
|
|
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
|
+
},
|
|
46
71
|
|
|
47
|
-
|
|
72
|
+
// Unicode tests
|
|
48
73
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
},
|
|
52
|
-
function test_matchInvalid(t) {
|
|
53
|
-
"use strict";
|
|
74
|
+
function test_matchUnicode(t) {
|
|
75
|
+
'use strict';
|
|
54
76
|
|
|
55
|
-
|
|
77
|
+
var str = 'Это ГЛАВА 3.4.5.1';
|
|
56
78
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
t.test(false); // shouldn't be here
|
|
60
|
-
} catch(e) {
|
|
61
|
-
eval(t.TEST("e === 'corner'"));
|
|
62
|
-
}
|
|
63
|
-
},
|
|
79
|
+
var re = new RE2(/(глава \d+(\.\d)*)/i);
|
|
80
|
+
var result = re.match(str);
|
|
64
81
|
|
|
65
|
-
|
|
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
|
+
},
|
|
66
89
|
|
|
67
|
-
|
|
68
|
-
"use strict";
|
|
90
|
+
// Buffer tests
|
|
69
91
|
|
|
70
|
-
|
|
92
|
+
function test_matchBuffer(t) {
|
|
93
|
+
'use strict';
|
|
71
94
|
|
|
72
|
-
|
|
73
|
-
var result = re.match(str);
|
|
95
|
+
var buf = new Buffer('Это ГЛАВА 3.4.5.1');
|
|
74
96
|
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
},
|
|
97
|
+
var re = new RE2(/(глава \d+(\.\d)*)/i);
|
|
98
|
+
var result = re.match(buf);
|
|
82
99
|
|
|
83
|
-
|
|
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'));
|
|
84
105
|
|
|
85
|
-
|
|
86
|
-
|
|
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
|
+
},
|
|
87
115
|
|
|
88
|
-
|
|
116
|
+
// Sticky tests
|
|
89
117
|
|
|
90
|
-
|
|
91
|
-
|
|
118
|
+
function test_matchSticky(t) {
|
|
119
|
+
'use strict';
|
|
92
120
|
|
|
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"));
|
|
121
|
+
var re = new RE2('\\s+', 'y');
|
|
98
122
|
|
|
99
|
-
|
|
100
|
-
eval(t.TEST("result.index === 7"));
|
|
101
|
-
eval(t.TEST("result.input.toString('utf8', result.index) === 'ГЛАВА 3.4.5.1'"));
|
|
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
|
-
},
|
|
123
|
+
eval(t.TEST("re.match('Hello world, how are you?') === null"));
|
|
106
124
|
|
|
107
|
-
|
|
125
|
+
re.lastIndex = 5;
|
|
108
126
|
|
|
109
|
-
|
|
110
|
-
"use strict";
|
|
127
|
+
var result = re.match('Hello world, how are you?');
|
|
111
128
|
|
|
112
|
-
|
|
129
|
+
eval(t.TEST("t.unify(result, [' '])"));
|
|
130
|
+
eval(t.TEST('result.index === 5'));
|
|
131
|
+
eval(t.TEST('re.lastIndex === 6'));
|
|
113
132
|
|
|
114
|
-
|
|
133
|
+
var re2 = new RE2('\\s+', 'gy');
|
|
115
134
|
|
|
116
|
-
|
|
135
|
+
eval(t.TEST("re2.match('Hello world, how are you?') === null"));
|
|
117
136
|
|
|
118
|
-
|
|
137
|
+
re2.lastIndex = 5;
|
|
119
138
|
|
|
120
|
-
|
|
121
|
-
eval(t.TEST("result.index === 5"));
|
|
122
|
-
eval(t.TEST("re.lastIndex === 6"));
|
|
139
|
+
eval(t.TEST("re2.match('Hello world, how are you?') === null"));
|
|
123
140
|
|
|
124
|
-
|
|
141
|
+
var re3 = new RE2(/[A-E]/giy);
|
|
142
|
+
var result3 = re3.match(
|
|
143
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
|
144
|
+
);
|
|
125
145
|
|
|
126
|
-
|
|
146
|
+
eval(t.TEST("t.unify(result3, ['A', 'B', 'C', 'D', 'E'])"));
|
|
147
|
+
},
|
|
127
148
|
|
|
128
|
-
|
|
149
|
+
// hasIndices tests
|
|
129
150
|
|
|
130
|
-
|
|
151
|
+
function test_matchHasIndices(t) {
|
|
152
|
+
'use strict';
|
|
131
153
|
|
|
132
|
-
|
|
133
|
-
|
|
154
|
+
var re = new RE2('(aa)(?<b>b)?(?<c>ccc)', 'd'),
|
|
155
|
+
str1 = '1aabccc2',
|
|
156
|
+
str2 = '1aaccc2';
|
|
134
157
|
|
|
135
|
-
|
|
136
|
-
|
|
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
|
+
}
|
|
137
161
|
]);
|
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
|
}
|