re2js 1.3.0 → 1.3.2

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.
@@ -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?: any);
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?: any);
477
+ constructor(charSequence?: null);
463
478
  charSequence: any;
464
479
  getEncoding(): any;
465
480
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.d.ts","sourceRoot":"","sources":["index.esm.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.d.ts","sourceRoot":"","sources":["index.esm.js"],"names":[],"mappings":"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"}
@@ -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.0
5
+ * @version v1.3.2
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(id, nfaStates, isMatch) {
2126
- this.id = id; // Stringified NFA state list (e.g., "1,4,7")
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 (unanchored)
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(); // id -> DFAState
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), like RE2 max_mem
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 id = closureResult.pcs.join(',');
2183
- if (this.stateCache.has(id)) {
2184
- return this.stateCache.get(id);
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
- if (this.stateCache.size > this.stateLimit) {
2189
- throw new RE2JSDfaMemoryException('dfa error: Out of memory exception');
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
- const state = new DFAState(id, closureResult.pcs, closureResult.isMatch);
2192
- this.stateCache.set(id, state);
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
- try {
5419
- const dfaResult = this.dfa.match(input, pos, anchor);
5420
- if (dfaResult !== null) {
5421
- // DFA succeeded (returned true or false)
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
@@ -6228,7 +6253,7 @@ class RE2JS {
6228
6253
  * @throws RE2JSSyntaxException if the regular expression is malformed
6229
6254
  */
6230
6255
  static matches(regex, input) {
6231
- return RE2JS.compile(regex).matcher(input).matches();
6256
+ return RE2JS.compile(regex).testExact(input);
6232
6257
  }
6233
6258
 
6234
6259
  /**
@@ -6294,7 +6319,7 @@ class RE2JS {
6294
6319
  * @returns {boolean} true if the regular expression matches the entire input
6295
6320
  */
6296
6321
  matches(input) {
6297
- return this.matcher(input).matches();
6322
+ return this.testExact(input);
6298
6323
  }
6299
6324
 
6300
6325
  /**
@@ -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, RE2JSDfaMemoryException, RE2JSException, RE2JSFlagsException, RE2JSGroupException, RE2JSSyntaxException };
6489
+ export { Matcher, RE2JS, RE2JSCompileException, RE2JSException, RE2JSFlagsException, RE2JSGroupException, RE2JSSyntaxException };
6432
6490
  //# sourceMappingURL=index.esm.js.map