re2js 1.3.0 → 1.3.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 +34 -0
- package/build/index.cjs.cjs +270 -213
- package/build/index.cjs.cjs.map +1 -1
- package/build/index.esm.d.ts +28 -13
- package/build/index.esm.d.ts.map +1 -1
- package/build/index.esm.js +271 -213
- package/build/index.esm.js.map +1 -1
- package/build/index.umd.js +270 -213
- package/build/index.umd.js.map +1 -1
- package/package.json +12 -12
package/build/index.esm.d.ts
CHANGED
|
@@ -56,19 +56,19 @@ export class Matcher {
|
|
|
56
56
|
*/
|
|
57
57
|
reset(): Matcher;
|
|
58
58
|
/** @type {number} */
|
|
59
|
-
matcherInputLength: number;
|
|
59
|
+
matcherInputLength: number | undefined;
|
|
60
60
|
/** @type {number} */
|
|
61
|
-
appendPos: number;
|
|
62
|
-
hasMatch: boolean;
|
|
63
|
-
hasGroups: boolean;
|
|
64
|
-
anchorFlag: number;
|
|
61
|
+
appendPos: number | undefined;
|
|
62
|
+
hasMatch: boolean | undefined;
|
|
63
|
+
hasGroups: boolean | undefined;
|
|
64
|
+
anchorFlag: number | undefined;
|
|
65
65
|
/**
|
|
66
66
|
* Resets the {@code Matcher} and changes the input.
|
|
67
67
|
* @param {Utf8MatcherInput|Utf16MatcherInput} input
|
|
68
68
|
* @returns {Matcher} the {@code Matcher} itself, for chained method calls
|
|
69
69
|
*/
|
|
70
70
|
resetMatcherInput(input: Utf8MatcherInput | Utf16MatcherInput): Matcher;
|
|
71
|
-
matcherInput: Utf8MatcherInput | Utf16MatcherInput;
|
|
71
|
+
matcherInput: Utf8MatcherInput | Utf16MatcherInput | undefined;
|
|
72
72
|
/**
|
|
73
73
|
* Returns the start of the named group of the most recent match, or -1 if the group was not
|
|
74
74
|
* matched.
|
|
@@ -340,6 +340,26 @@ export class RE2JS {
|
|
|
340
340
|
* @returns {Matcher}
|
|
341
341
|
*/
|
|
342
342
|
matcher(input: string | number[]): Matcher;
|
|
343
|
+
/**
|
|
344
|
+
* Tests whether the regular expression matches any part of the input string.
|
|
345
|
+
* Performance Note: This method is highly optimized. Because it only returns
|
|
346
|
+
* a boolean and does not extract capture groups, it bypasses the `Matcher` overhead
|
|
347
|
+
* and guarantees execution on the high-speed DFA engine whenever possible.
|
|
348
|
+
*
|
|
349
|
+
* @param {string|number[]} input - The input string or UTF-8 byte array to test against.
|
|
350
|
+
* @returns {boolean} `true` if the pattern is found anywhere in the input, `false` otherwise.
|
|
351
|
+
*/
|
|
352
|
+
test(input: string | number[]): boolean;
|
|
353
|
+
/**
|
|
354
|
+
* Tests whether the regular expression matches the ENTIRE input string.
|
|
355
|
+
* * **Performance Note:** This operates identically to `.matches()`, but is significantly
|
|
356
|
+
* faster because it does not request capture group data. By requesting 0 capture groups,
|
|
357
|
+
* it securely routes execution through the DFA fast-path.
|
|
358
|
+
*
|
|
359
|
+
* @param {string|number[]} input - The input string or UTF-8 byte array to test against.
|
|
360
|
+
* @returns {boolean} `true` if the exact input string fully matches the pattern, `false` otherwise.
|
|
361
|
+
*/
|
|
362
|
+
testExact(input: string | number[]): boolean;
|
|
343
363
|
/**
|
|
344
364
|
* Splits input around instances of the regular expression. It returns an array giving the strings
|
|
345
365
|
* that occur before, between, and after instances of the regular expression.
|
|
@@ -395,11 +415,6 @@ export class RE2JS {
|
|
|
395
415
|
*/
|
|
396
416
|
export class RE2JSCompileException extends RE2JSException {
|
|
397
417
|
}
|
|
398
|
-
/**
|
|
399
|
-
* An exception thrown by DFA
|
|
400
|
-
*/
|
|
401
|
-
export class RE2JSDfaMemoryException extends RE2JSException {
|
|
402
|
-
}
|
|
403
418
|
export class RE2JSException extends Error {
|
|
404
419
|
/** @param {string} message */
|
|
405
420
|
constructor(message: string);
|
|
@@ -439,7 +454,7 @@ export class RE2JSSyntaxException extends RE2JSException {
|
|
|
439
454
|
getPattern(): string | null;
|
|
440
455
|
}
|
|
441
456
|
declare class Utf8MatcherInput extends MatcherInputBase {
|
|
442
|
-
constructor(bytes?:
|
|
457
|
+
constructor(bytes?: null);
|
|
443
458
|
bytes: any;
|
|
444
459
|
getEncoding(): any;
|
|
445
460
|
/**
|
|
@@ -459,7 +474,7 @@ declare class Utf8MatcherInput extends MatcherInputBase {
|
|
|
459
474
|
length(): number;
|
|
460
475
|
}
|
|
461
476
|
declare class Utf16MatcherInput extends MatcherInputBase {
|
|
462
|
-
constructor(charSequence?:
|
|
477
|
+
constructor(charSequence?: null);
|
|
463
478
|
charSequence: any;
|
|
464
479
|
getEncoding(): any;
|
|
465
480
|
/**
|
package/build/index.esm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.d.ts","sourceRoot":"","sources":["index.esm.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.d.ts","sourceRoot":"","sources":["index.esm.js"],"names":[],"mappings":"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"}
|
package/build/index.esm.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* re2js
|
|
3
3
|
* RE2JS is the JavaScript port of RE2, a regular expression engine that provides linear time matching
|
|
4
4
|
*
|
|
5
|
-
* @version v1.3.
|
|
5
|
+
* @version v1.3.1
|
|
6
6
|
* @author Alexey Vasiliev
|
|
7
7
|
* @homepage https://github.com/le0pard/re2js#readme
|
|
8
8
|
* @repository github:le0pard/re2js
|
|
@@ -841,6 +841,181 @@ class MatcherInput {
|
|
|
841
841
|
}
|
|
842
842
|
}
|
|
843
843
|
|
|
844
|
+
/**
|
|
845
|
+
* MachineInput abstracts different representations of the input text supplied to the Machine. It
|
|
846
|
+
* provides one-character lookahead.
|
|
847
|
+
*/
|
|
848
|
+
class MachineInputBase {
|
|
849
|
+
static EOF() {
|
|
850
|
+
return -1 << 3;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// can we look ahead without losing info?
|
|
854
|
+
canCheckPrefix() {
|
|
855
|
+
return true;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// Returns the end position in the same units as step().
|
|
859
|
+
endPos() {
|
|
860
|
+
return this.end;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
// An implementation of MachineInput for UTF-8 byte arrays.
|
|
865
|
+
// |pos| and |width| are byte indices.
|
|
866
|
+
class MachineUTF8Input extends MachineInputBase {
|
|
867
|
+
constructor(bytes, start = 0, end = bytes.length) {
|
|
868
|
+
super();
|
|
869
|
+
this.bytes = bytes;
|
|
870
|
+
this.start = start;
|
|
871
|
+
this.end = end;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// Returns the rune at the specified index; the units are
|
|
875
|
+
// unspecified, but could be UTF-8 byte, UTF-16 char, or rune
|
|
876
|
+
// indices. Returns the width (in the same units) of the rune in
|
|
877
|
+
// the lower 3 bits, and the rune (Unicode code point) in the high
|
|
878
|
+
// bits. Never negative, except for EOF which is represented as -1
|
|
879
|
+
// << 3 | 0.
|
|
880
|
+
step(i) {
|
|
881
|
+
i += this.start;
|
|
882
|
+
if (i >= this.end) {
|
|
883
|
+
return MachineInputBase.EOF();
|
|
884
|
+
}
|
|
885
|
+
let x = this.bytes[i++] & 255;
|
|
886
|
+
if ((x & 128) === 0) {
|
|
887
|
+
return x << 3 | 1;
|
|
888
|
+
} else if ((x & 224) === 192) {
|
|
889
|
+
x = x & 31;
|
|
890
|
+
if (i >= this.end) {
|
|
891
|
+
return MachineInputBase.EOF();
|
|
892
|
+
}
|
|
893
|
+
x = x << 6 | this.bytes[i++] & 63;
|
|
894
|
+
return x << 3 | 2;
|
|
895
|
+
} else if ((x & 240) === 224) {
|
|
896
|
+
x = x & 15;
|
|
897
|
+
if (i + 1 >= this.end) {
|
|
898
|
+
return MachineInputBase.EOF();
|
|
899
|
+
}
|
|
900
|
+
x = x << 6 | this.bytes[i++] & 63;
|
|
901
|
+
x = x << 6 | this.bytes[i++] & 63;
|
|
902
|
+
return x << 3 | 3;
|
|
903
|
+
} else {
|
|
904
|
+
x = x & 7;
|
|
905
|
+
if (i + 2 >= this.end) {
|
|
906
|
+
return MachineInputBase.EOF();
|
|
907
|
+
}
|
|
908
|
+
x = x << 6 | this.bytes[i++] & 63;
|
|
909
|
+
x = x << 6 | this.bytes[i++] & 63;
|
|
910
|
+
x = x << 6 | this.bytes[i++] & 63;
|
|
911
|
+
return x << 3 | 4;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// Returns the index relative to |pos| at which |re2.prefix| is found
|
|
916
|
+
// in this input stream, or a negative value if not found.
|
|
917
|
+
index(re2, pos) {
|
|
918
|
+
pos += this.start;
|
|
919
|
+
const i = this.indexOf(this.bytes, re2.prefixUTF8, pos);
|
|
920
|
+
return i < 0 ? i : i - pos;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// Returns a bitmask of EMPTY_* flags.
|
|
924
|
+
context(pos) {
|
|
925
|
+
pos += this.start;
|
|
926
|
+
let r1 = -1;
|
|
927
|
+
if (pos > this.start && pos <= this.end) {
|
|
928
|
+
let start = pos - 1;
|
|
929
|
+
r1 = this.bytes[start--];
|
|
930
|
+
if (r1 >= 128) {
|
|
931
|
+
let lim = pos - 4;
|
|
932
|
+
if (lim < this.start) {
|
|
933
|
+
lim = this.start;
|
|
934
|
+
}
|
|
935
|
+
while (start >= lim && (this.bytes[start] & 192) === 128) {
|
|
936
|
+
start--;
|
|
937
|
+
}
|
|
938
|
+
if (start < this.start) {
|
|
939
|
+
start = this.start;
|
|
940
|
+
}
|
|
941
|
+
r1 = this.step(start) >> 3;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
const r2 = pos < this.end ? this.step(pos) >> 3 : -1;
|
|
945
|
+
return Utils.emptyOpContext(r1, r2);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
// Returns the index of the first occurrence of array |target| within
|
|
949
|
+
// array |source| after |fromIndex|, or -1 if not found.
|
|
950
|
+
indexOf(source, target, fromIndex = 0) {
|
|
951
|
+
let targetLength = target.length;
|
|
952
|
+
if (targetLength === 0) {
|
|
953
|
+
return -1;
|
|
954
|
+
}
|
|
955
|
+
let sourceLength = source.length;
|
|
956
|
+
for (let i = fromIndex; i <= sourceLength - targetLength; i++) {
|
|
957
|
+
for (let j = 0; j < targetLength; j++) {
|
|
958
|
+
if (source[i + j] !== target[j]) {
|
|
959
|
+
break;
|
|
960
|
+
} else if (j === targetLength - 1) {
|
|
961
|
+
return i;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
return -1;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// |pos| and |width| are in JS "char" units.
|
|
970
|
+
class MachineUTF16Input extends MachineInputBase {
|
|
971
|
+
constructor(charSequence, start = 0, end = charSequence.length) {
|
|
972
|
+
super();
|
|
973
|
+
this.charSequence = charSequence;
|
|
974
|
+
this.start = start;
|
|
975
|
+
this.end = end;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
// Returns the rune at the specified index; the units are
|
|
979
|
+
// unspecified, but could be UTF-8 byte, UTF-16 char, or rune
|
|
980
|
+
// indices. Returns the width (in the same units) of the rune in
|
|
981
|
+
// the lower 3 bits, and the rune (Unicode code point) in the high
|
|
982
|
+
// bits. Never negative, except for EOF which is represented as -1
|
|
983
|
+
// << 3 | 0.
|
|
984
|
+
step(pos) {
|
|
985
|
+
pos += this.start;
|
|
986
|
+
if (pos < this.end) {
|
|
987
|
+
const rune = this.charSequence.codePointAt(pos);
|
|
988
|
+
return rune << 3 | Utils.charCount(rune);
|
|
989
|
+
} else {
|
|
990
|
+
return MachineInputBase.EOF();
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
// Returns the index relative to |pos| at which |re2.prefix| is found
|
|
995
|
+
// in this input stream, or a negative value if not found.
|
|
996
|
+
index(re2, pos) {
|
|
997
|
+
pos += this.start;
|
|
998
|
+
const i = this.charSequence.indexOf(re2.prefix, pos);
|
|
999
|
+
return i < 0 ? i : i - pos;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// Returns a bitmask of EMPTY_* flags.
|
|
1003
|
+
context(pos) {
|
|
1004
|
+
pos += this.start;
|
|
1005
|
+
const r1 = pos > 0 && pos <= this.charSequence.length ? this.charSequence.codePointAt(pos - 1) : -1;
|
|
1006
|
+
const r2 = pos < this.charSequence.length ? this.charSequence.codePointAt(pos) : -1;
|
|
1007
|
+
return Utils.emptyOpContext(r1, r2);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
class MachineInput {
|
|
1011
|
+
static fromUTF8(bytes, start = 0, end = bytes.length) {
|
|
1012
|
+
return new MachineUTF8Input(bytes, start, end);
|
|
1013
|
+
}
|
|
1014
|
+
static fromUTF16(charSequence, start = 0, end = charSequence.length) {
|
|
1015
|
+
return new MachineUTF16Input(charSequence, start, end);
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
|
|
844
1019
|
class RE2JSException extends Error {
|
|
845
1020
|
/** @param {string} message */
|
|
846
1021
|
constructor(message) {
|
|
@@ -921,17 +1096,6 @@ class RE2JSFlagsException extends RE2JSException {
|
|
|
921
1096
|
}
|
|
922
1097
|
}
|
|
923
1098
|
|
|
924
|
-
/**
|
|
925
|
-
* An exception thrown by DFA
|
|
926
|
-
*/
|
|
927
|
-
class RE2JSDfaMemoryException extends RE2JSException {
|
|
928
|
-
/** @param {string} message */
|
|
929
|
-
constructor(message) {
|
|
930
|
-
super(message);
|
|
931
|
-
this.name = 'RE2JSDfaMemoryException';
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
|
|
935
1099
|
/**
|
|
936
1100
|
* A stateful iterator that interprets a regex {@code RE2JS} on a specific input.
|
|
937
1101
|
*
|
|
@@ -1488,181 +1652,6 @@ class Matcher {
|
|
|
1488
1652
|
}
|
|
1489
1653
|
}
|
|
1490
1654
|
|
|
1491
|
-
/**
|
|
1492
|
-
* MachineInput abstracts different representations of the input text supplied to the Machine. It
|
|
1493
|
-
* provides one-character lookahead.
|
|
1494
|
-
*/
|
|
1495
|
-
class MachineInputBase {
|
|
1496
|
-
static EOF() {
|
|
1497
|
-
return -1 << 3;
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
|
-
// can we look ahead without losing info?
|
|
1501
|
-
canCheckPrefix() {
|
|
1502
|
-
return true;
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
|
-
// Returns the end position in the same units as step().
|
|
1506
|
-
endPos() {
|
|
1507
|
-
return this.end;
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
|
|
1511
|
-
// An implementation of MachineInput for UTF-8 byte arrays.
|
|
1512
|
-
// |pos| and |width| are byte indices.
|
|
1513
|
-
class MachineUTF8Input extends MachineInputBase {
|
|
1514
|
-
constructor(bytes, start = 0, end = bytes.length) {
|
|
1515
|
-
super();
|
|
1516
|
-
this.bytes = bytes;
|
|
1517
|
-
this.start = start;
|
|
1518
|
-
this.end = end;
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
// Returns the rune at the specified index; the units are
|
|
1522
|
-
// unspecified, but could be UTF-8 byte, UTF-16 char, or rune
|
|
1523
|
-
// indices. Returns the width (in the same units) of the rune in
|
|
1524
|
-
// the lower 3 bits, and the rune (Unicode code point) in the high
|
|
1525
|
-
// bits. Never negative, except for EOF which is represented as -1
|
|
1526
|
-
// << 3 | 0.
|
|
1527
|
-
step(i) {
|
|
1528
|
-
i += this.start;
|
|
1529
|
-
if (i >= this.end) {
|
|
1530
|
-
return MachineInputBase.EOF();
|
|
1531
|
-
}
|
|
1532
|
-
let x = this.bytes[i++] & 255;
|
|
1533
|
-
if ((x & 128) === 0) {
|
|
1534
|
-
return x << 3 | 1;
|
|
1535
|
-
} else if ((x & 224) === 192) {
|
|
1536
|
-
x = x & 31;
|
|
1537
|
-
if (i >= this.end) {
|
|
1538
|
-
return MachineInputBase.EOF();
|
|
1539
|
-
}
|
|
1540
|
-
x = x << 6 | this.bytes[i++] & 63;
|
|
1541
|
-
return x << 3 | 2;
|
|
1542
|
-
} else if ((x & 240) === 224) {
|
|
1543
|
-
x = x & 15;
|
|
1544
|
-
if (i + 1 >= this.end) {
|
|
1545
|
-
return MachineInputBase.EOF();
|
|
1546
|
-
}
|
|
1547
|
-
x = x << 6 | this.bytes[i++] & 63;
|
|
1548
|
-
x = x << 6 | this.bytes[i++] & 63;
|
|
1549
|
-
return x << 3 | 3;
|
|
1550
|
-
} else {
|
|
1551
|
-
x = x & 7;
|
|
1552
|
-
if (i + 2 >= this.end) {
|
|
1553
|
-
return MachineInputBase.EOF();
|
|
1554
|
-
}
|
|
1555
|
-
x = x << 6 | this.bytes[i++] & 63;
|
|
1556
|
-
x = x << 6 | this.bytes[i++] & 63;
|
|
1557
|
-
x = x << 6 | this.bytes[i++] & 63;
|
|
1558
|
-
return x << 3 | 4;
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
// Returns the index relative to |pos| at which |re2.prefix| is found
|
|
1563
|
-
// in this input stream, or a negative value if not found.
|
|
1564
|
-
index(re2, pos) {
|
|
1565
|
-
pos += this.start;
|
|
1566
|
-
const i = this.indexOf(this.bytes, re2.prefixUTF8, pos);
|
|
1567
|
-
return i < 0 ? i : i - pos;
|
|
1568
|
-
}
|
|
1569
|
-
|
|
1570
|
-
// Returns a bitmask of EMPTY_* flags.
|
|
1571
|
-
context(pos) {
|
|
1572
|
-
pos += this.start;
|
|
1573
|
-
let r1 = -1;
|
|
1574
|
-
if (pos > this.start && pos <= this.end) {
|
|
1575
|
-
let start = pos - 1;
|
|
1576
|
-
r1 = this.bytes[start--];
|
|
1577
|
-
if (r1 >= 128) {
|
|
1578
|
-
let lim = pos - 4;
|
|
1579
|
-
if (lim < this.start) {
|
|
1580
|
-
lim = this.start;
|
|
1581
|
-
}
|
|
1582
|
-
while (start >= lim && (this.bytes[start] & 192) === 128) {
|
|
1583
|
-
start--;
|
|
1584
|
-
}
|
|
1585
|
-
if (start < this.start) {
|
|
1586
|
-
start = this.start;
|
|
1587
|
-
}
|
|
1588
|
-
r1 = this.step(start) >> 3;
|
|
1589
|
-
}
|
|
1590
|
-
}
|
|
1591
|
-
const r2 = pos < this.end ? this.step(pos) >> 3 : -1;
|
|
1592
|
-
return Utils.emptyOpContext(r1, r2);
|
|
1593
|
-
}
|
|
1594
|
-
|
|
1595
|
-
// Returns the index of the first occurrence of array |target| within
|
|
1596
|
-
// array |source| after |fromIndex|, or -1 if not found.
|
|
1597
|
-
indexOf(source, target, fromIndex = 0) {
|
|
1598
|
-
let targetLength = target.length;
|
|
1599
|
-
if (targetLength === 0) {
|
|
1600
|
-
return -1;
|
|
1601
|
-
}
|
|
1602
|
-
let sourceLength = source.length;
|
|
1603
|
-
for (let i = fromIndex; i <= sourceLength - targetLength; i++) {
|
|
1604
|
-
for (let j = 0; j < targetLength; j++) {
|
|
1605
|
-
if (source[i + j] !== target[j]) {
|
|
1606
|
-
break;
|
|
1607
|
-
} else if (j === targetLength - 1) {
|
|
1608
|
-
return i;
|
|
1609
|
-
}
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
return -1;
|
|
1613
|
-
}
|
|
1614
|
-
}
|
|
1615
|
-
|
|
1616
|
-
// |pos| and |width| are in JS "char" units.
|
|
1617
|
-
class MachineUTF16Input extends MachineInputBase {
|
|
1618
|
-
constructor(charSequence, start = 0, end = charSequence.length) {
|
|
1619
|
-
super();
|
|
1620
|
-
this.charSequence = charSequence;
|
|
1621
|
-
this.start = start;
|
|
1622
|
-
this.end = end;
|
|
1623
|
-
}
|
|
1624
|
-
|
|
1625
|
-
// Returns the rune at the specified index; the units are
|
|
1626
|
-
// unspecified, but could be UTF-8 byte, UTF-16 char, or rune
|
|
1627
|
-
// indices. Returns the width (in the same units) of the rune in
|
|
1628
|
-
// the lower 3 bits, and the rune (Unicode code point) in the high
|
|
1629
|
-
// bits. Never negative, except for EOF which is represented as -1
|
|
1630
|
-
// << 3 | 0.
|
|
1631
|
-
step(pos) {
|
|
1632
|
-
pos += this.start;
|
|
1633
|
-
if (pos < this.end) {
|
|
1634
|
-
const rune = this.charSequence.codePointAt(pos);
|
|
1635
|
-
return rune << 3 | Utils.charCount(rune);
|
|
1636
|
-
} else {
|
|
1637
|
-
return MachineInputBase.EOF();
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
|
|
1641
|
-
// Returns the index relative to |pos| at which |re2.prefix| is found
|
|
1642
|
-
// in this input stream, or a negative value if not found.
|
|
1643
|
-
index(re2, pos) {
|
|
1644
|
-
pos += this.start;
|
|
1645
|
-
const i = this.charSequence.indexOf(re2.prefix, pos);
|
|
1646
|
-
return i < 0 ? i : i - pos;
|
|
1647
|
-
}
|
|
1648
|
-
|
|
1649
|
-
// Returns a bitmask of EMPTY_* flags.
|
|
1650
|
-
context(pos) {
|
|
1651
|
-
pos += this.start;
|
|
1652
|
-
const r1 = pos > 0 && pos <= this.charSequence.length ? this.charSequence.codePointAt(pos - 1) : -1;
|
|
1653
|
-
const r2 = pos < this.charSequence.length ? this.charSequence.codePointAt(pos) : -1;
|
|
1654
|
-
return Utils.emptyOpContext(r1, r2);
|
|
1655
|
-
}
|
|
1656
|
-
}
|
|
1657
|
-
class MachineInput {
|
|
1658
|
-
static fromUTF8(bytes, start = 0, end = bytes.length) {
|
|
1659
|
-
return new MachineUTF8Input(bytes, start, end);
|
|
1660
|
-
}
|
|
1661
|
-
static fromUTF16(charSequence, start = 0, end = charSequence.length) {
|
|
1662
|
-
return new MachineUTF16Input(charSequence, start, end);
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
|
|
1666
1655
|
/**
|
|
1667
1656
|
* A single instruction in the regular expression virtual machine.
|
|
1668
1657
|
*
|
|
@@ -2121,21 +2110,40 @@ class Machine {
|
|
|
2121
2110
|
}
|
|
2122
2111
|
}
|
|
2123
2112
|
|
|
2113
|
+
// FNV-1a 32-bit hash for an array of integers.
|
|
2114
|
+
// Extremely fast, allocates no memory, and produces good distribution.
|
|
2115
|
+
const hashPCs = pcs => {
|
|
2116
|
+
let h = -2128831035; // 0x811c9dc5 (32-bit signed offset basis)
|
|
2117
|
+
for (let i = 0; i < pcs.length; i++) {
|
|
2118
|
+
h ^= pcs[i];
|
|
2119
|
+
h = Math.imul(h, 16777619); // 0x01000193 (FNV prime)
|
|
2120
|
+
}
|
|
2121
|
+
return h;
|
|
2122
|
+
};
|
|
2123
|
+
|
|
2124
|
+
// Zero-allocation array comparison for hash collision resolution
|
|
2125
|
+
const arraysEqual = (a, b) => {
|
|
2126
|
+
if (a.length !== b.length) return false;
|
|
2127
|
+
for (let i = 0; i < a.length; i++) {
|
|
2128
|
+
if (a[i] !== b[i]) return false;
|
|
2129
|
+
}
|
|
2130
|
+
return true;
|
|
2131
|
+
};
|
|
2124
2132
|
class DFAState {
|
|
2125
|
-
constructor(
|
|
2126
|
-
this.
|
|
2127
|
-
this.nfaStates = nfaStates; // Array of Instruction PCs
|
|
2133
|
+
constructor(nfaStates, isMatch) {
|
|
2134
|
+
this.nfaStates = nfaStates; // Int32Array of Instruction PCs
|
|
2128
2135
|
this.isMatch = isMatch; // Boolean
|
|
2129
|
-
this.nextAscii = new Array(Unicode.MAX_ASCII + 1).fill(null); // Flat array for blisteringly fast ASCII lookups
|
|
2136
|
+
this.nextAscii = new Array(Unicode.MAX_ASCII + 1).fill(null); // Flat array for blisteringly fast ASCII lookups
|
|
2130
2137
|
this.nextMap = new Map(); // Cache of Char -> DFAState
|
|
2131
2138
|
}
|
|
2132
2139
|
}
|
|
2133
2140
|
class DFA {
|
|
2134
2141
|
constructor(prog) {
|
|
2135
2142
|
this.prog = prog;
|
|
2136
|
-
this.stateCache = new Map(); //
|
|
2143
|
+
this.stateCache = new Map(); // hash(number) -> DFAState[]
|
|
2144
|
+
this.stateCount = 0; // Tracks total states for memory limits
|
|
2137
2145
|
this.startState = null;
|
|
2138
|
-
this.stateLimit = 10000; // Prevent memory explosion (ReDoS protection)
|
|
2146
|
+
this.stateLimit = 10000; // Prevent memory explosion (ReDoS protection)
|
|
2139
2147
|
}
|
|
2140
2148
|
|
|
2141
2149
|
// Follows epsilon (empty) transitions to find all reachable states without consuming a char
|
|
@@ -2179,17 +2187,37 @@ class DFA {
|
|
|
2179
2187
|
const closureResult = this.computeClosure(pcs);
|
|
2180
2188
|
if (!closureResult) return null; // Bailout to NFA required
|
|
2181
2189
|
|
|
2182
|
-
const
|
|
2183
|
-
|
|
2184
|
-
|
|
2190
|
+
const sortedPCs = closureResult.pcs;
|
|
2191
|
+
const hash = hashPCs(sortedPCs);
|
|
2192
|
+
|
|
2193
|
+
// Lookup hash bucket
|
|
2194
|
+
let bucket = this.stateCache.get(hash);
|
|
2195
|
+
if (bucket) {
|
|
2196
|
+
// Resolve potential hash collisions
|
|
2197
|
+
for (let i = 0; i < bucket.length; i++) {
|
|
2198
|
+
const state = bucket[i];
|
|
2199
|
+
if (arraysEqual(state.nfaStates, sortedPCs)) {
|
|
2200
|
+
return state;
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
} else {
|
|
2204
|
+
bucket = [];
|
|
2205
|
+
this.stateCache.set(hash, bucket);
|
|
2185
2206
|
}
|
|
2186
2207
|
|
|
2187
2208
|
// Safety: prevent memory exhaustion from state explosion
|
|
2188
|
-
|
|
2189
|
-
|
|
2209
|
+
// We flush the cache and return null, which seamlessly routes execution to the NFA
|
|
2210
|
+
if (this.stateCount >= this.stateLimit) {
|
|
2211
|
+
this.stateCache.clear();
|
|
2212
|
+
this.stateCount = 0;
|
|
2213
|
+
this.startState = null;
|
|
2214
|
+
return null;
|
|
2190
2215
|
}
|
|
2191
|
-
|
|
2192
|
-
|
|
2216
|
+
|
|
2217
|
+
// State not found, create it and add to bucket
|
|
2218
|
+
const state = new DFAState(sortedPCs, closureResult.isMatch);
|
|
2219
|
+
bucket.push(state);
|
|
2220
|
+
this.stateCount++;
|
|
2193
2221
|
return state;
|
|
2194
2222
|
}
|
|
2195
2223
|
|
|
@@ -2253,6 +2281,11 @@ class DFA {
|
|
|
2253
2281
|
const r = input.step(i);
|
|
2254
2282
|
const rune = r >> 3;
|
|
2255
2283
|
const width = r & 7;
|
|
2284
|
+
|
|
2285
|
+
// prevent infinite loop on EOF
|
|
2286
|
+
if (width === 0) {
|
|
2287
|
+
break;
|
|
2288
|
+
}
|
|
2256
2289
|
currentState = this.step(currentState, rune, anchor);
|
|
2257
2290
|
|
|
2258
2291
|
// If we hit an unrecoverable DFA error or bailout, signal fallback
|
|
@@ -5415,18 +5448,10 @@ class RE2 {
|
|
|
5415
5448
|
if (ncap > 0) {
|
|
5416
5449
|
return this.doExecuteNFA(input, pos, anchor, ncap);
|
|
5417
5450
|
}
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
return dfaResult ? [] : null; // Return empty array to signify "matched but no captures"
|
|
5423
|
-
}
|
|
5424
|
-
} catch (e) {
|
|
5425
|
-
if (e instanceof RE2JSDfaMemoryException) {
|
|
5426
|
-
this.dfa = new DFA(this.prog); // flush cache
|
|
5427
|
-
} else {
|
|
5428
|
-
throw e;
|
|
5429
|
-
}
|
|
5451
|
+
const dfaResult = this.dfa.match(input, pos, anchor);
|
|
5452
|
+
if (dfaResult !== null) {
|
|
5453
|
+
// DFA succeeded (returned true or false)
|
|
5454
|
+
return dfaResult ? [] : null; // Return empty array to signify "matched but no captures"
|
|
5430
5455
|
}
|
|
5431
5456
|
|
|
5432
5457
|
// Fallback to NFA
|
|
@@ -6310,6 +6335,39 @@ class RE2JS {
|
|
|
6310
6335
|
return new Matcher(this, input);
|
|
6311
6336
|
}
|
|
6312
6337
|
|
|
6338
|
+
/**
|
|
6339
|
+
* Tests whether the regular expression matches any part of the input string.
|
|
6340
|
+
* Performance Note: This method is highly optimized. Because it only returns
|
|
6341
|
+
* a boolean and does not extract capture groups, it bypasses the `Matcher` overhead
|
|
6342
|
+
* and guarantees execution on the high-speed DFA engine whenever possible.
|
|
6343
|
+
*
|
|
6344
|
+
* @param {string|number[]} input - The input string or UTF-8 byte array to test against.
|
|
6345
|
+
* @returns {boolean} `true` if the pattern is found anywhere in the input, `false` otherwise.
|
|
6346
|
+
*/
|
|
6347
|
+
test(input) {
|
|
6348
|
+
if (Array.isArray(input)) {
|
|
6349
|
+
// Reuse the existing UTF-8 fast-path method
|
|
6350
|
+
return this.re2Input.matchUTF8(input);
|
|
6351
|
+
}
|
|
6352
|
+
|
|
6353
|
+
// Reuse the existing UTF-16 fast-path method
|
|
6354
|
+
return this.re2Input.match(input);
|
|
6355
|
+
}
|
|
6356
|
+
|
|
6357
|
+
/**
|
|
6358
|
+
* Tests whether the regular expression matches the ENTIRE input string.
|
|
6359
|
+
* * **Performance Note:** This operates identically to `.matches()`, but is significantly
|
|
6360
|
+
* faster because it does not request capture group data. By requesting 0 capture groups,
|
|
6361
|
+
* it securely routes execution through the DFA fast-path.
|
|
6362
|
+
*
|
|
6363
|
+
* @param {string|number[]} input - The input string or UTF-8 byte array to test against.
|
|
6364
|
+
* @returns {boolean} `true` if the exact input string fully matches the pattern, `false` otherwise.
|
|
6365
|
+
*/
|
|
6366
|
+
testExact(input) {
|
|
6367
|
+
const machineInput = Array.isArray(input) ? MachineInput.fromUTF8(input) : MachineInput.fromUTF16(input);
|
|
6368
|
+
return this.re2Input.executeEngine(machineInput, 0, RE2Flags.ANCHOR_BOTH, 0) !== null;
|
|
6369
|
+
}
|
|
6370
|
+
|
|
6313
6371
|
/**
|
|
6314
6372
|
* Splits input around instances of the regular expression. It returns an array giving the strings
|
|
6315
6373
|
* that occur before, between, and after instances of the regular expression.
|
|
@@ -6428,5 +6486,5 @@ class RE2JS {
|
|
|
6428
6486
|
}
|
|
6429
6487
|
}
|
|
6430
6488
|
|
|
6431
|
-
export { Matcher, RE2JS, RE2JSCompileException,
|
|
6489
|
+
export { Matcher, RE2JS, RE2JSCompileException, RE2JSException, RE2JSFlagsException, RE2JSGroupException, RE2JSSyntaxException };
|
|
6432
6490
|
//# sourceMappingURL=index.esm.js.map
|