regex-partial-match 1.2.0 → 1.3.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 +146 -8
- package/lib/{extend.d.ts → extend/index.d.ts} +1 -1
- package/lib/{extend.js → extend/index.js} +1 -1
- package/lib/partialMatchRegExp/atomSyntax.d.ts +4 -0
- package/lib/partialMatchRegExp/atomSyntax.js +4 -0
- package/lib/partialMatchRegExp/backreferenceExpansion.d.ts +10 -0
- package/lib/partialMatchRegExp/backreferenceExpansion.js +1 -0
- package/lib/partialMatchRegExp/compilePartial/asNativeAtom.d.ts +2 -0
- package/lib/partialMatchRegExp/compilePartial/asNativeAtom.js +10 -0
- package/lib/partialMatchRegExp/compilePartial/asOptionalAtom.d.ts +1 -0
- package/lib/partialMatchRegExp/compilePartial/asOptionalAtom.js +4 -0
- package/lib/partialMatchRegExp/compilePartial/asPreScanPart.d.ts +2 -0
- package/lib/partialMatchRegExp/compilePartial/asPreScanPart.js +8 -0
- package/lib/partialMatchRegExp/compilePartial/caseFoldFlags.d.ts +1 -0
- package/lib/partialMatchRegExp/compilePartial/caseFoldFlags.js +3 -0
- package/lib/partialMatchRegExp/compilePartial/compiled.d.ts +29 -0
- package/lib/partialMatchRegExp/compilePartial/compiled.js +27 -0
- package/lib/partialMatchRegExp/compilePartial/flagsAtBackreference.d.ts +2 -0
- package/lib/partialMatchRegExp/compilePartial/flagsAtBackreference.js +4 -0
- package/lib/partialMatchRegExp/compilePartial/index.d.ts +2 -0
- package/lib/partialMatchRegExp/compilePartial/index.js +79 -0
- package/lib/partialMatchRegExp/compilePartial/longestBakedPrefixEndingInput.d.ts +1 -0
- package/lib/partialMatchRegExp/compilePartial/longestBakedPrefixEndingInput.js +50 -0
- package/lib/partialMatchRegExp/compilePartial/reclassifyLegacyEscapes.d.ts +2 -0
- package/lib/partialMatchRegExp/compilePartial/reclassifyLegacyEscapes.js +17 -0
- package/lib/partialMatchRegExp/compilePartial/renderParts.d.ts +2 -0
- package/lib/partialMatchRegExp/compilePartial/renderParts.js +9 -0
- package/lib/partialMatchRegExp/compilePartial/resolvedFromScan.d.ts +2 -0
- package/lib/partialMatchRegExp/compilePartial/resolvedFromScan.js +10 -0
- package/lib/partialMatchRegExp/compilePartial/spliceOriginalSource.d.ts +2 -0
- package/lib/partialMatchRegExp/compilePartial/spliceOriginalSource.js +12 -0
- package/lib/partialMatchRegExp/compilePartial/startsWithUnderFlags.d.ts +1 -0
- package/lib/partialMatchRegExp/compilePartial/startsWithUnderFlags.js +7 -0
- package/lib/partialMatchRegExp/compilePartial/toStatic.d.ts +3 -0
- package/lib/partialMatchRegExp/compilePartial/toStatic.js +4 -0
- package/lib/partialMatchRegExp/groupName.d.ts +2 -0
- package/lib/partialMatchRegExp/groupName.js +8 -0
- package/lib/partialMatchRegExp/index.d.ts +3 -0
- package/lib/partialMatchRegExp/index.js +3 -0
- package/lib/partialMatchRegExp/isComplete/index.d.ts +38 -0
- package/lib/partialMatchRegExp/isComplete/index.js +41 -0
- package/lib/partialMatchRegExp/isComplete/isMatchComplete.d.ts +3 -0
- package/lib/partialMatchRegExp/isComplete/isMatchComplete.js +14 -0
- package/lib/partialMatchRegExp/isComplete/partRole.d.ts +3 -0
- package/lib/partialMatchRegExp/isComplete/partRole.js +28 -0
- package/lib/partialMatchRegExp/isComplete/truncationProbe.d.ts +8 -0
- package/lib/partialMatchRegExp/isComplete/truncationProbe.js +105 -0
- package/lib/partialMatchRegExp/isComplete/truncationProbeCache.d.ts +4 -0
- package/lib/partialMatchRegExp/isComplete/truncationProbeCache.js +1 -0
- package/lib/partialMatchRegExp/legacyEscape.d.ts +2 -0
- package/lib/partialMatchRegExp/legacyEscape.js +18 -0
- package/lib/partialMatchRegExp/part.d.ts +24 -0
- package/lib/partialMatchRegExp/part.js +2 -0
- package/lib/partialMatchRegExp/partialMatchInternals.d.ts +2 -0
- package/lib/partialMatchRegExp/partialMatchInternals.js +2 -0
- package/lib/{partialMatchRegExp.d.ts → partialMatchRegExp/partialMatchRegExp.d.ts} +6 -3
- package/lib/{partialMatchRegExp.js → partialMatchRegExp/partialMatchRegExp.js} +23 -35
- package/lib/partialMatchRegExp/preferLongerCaptures.d.ts +1 -0
- package/lib/partialMatchRegExp/preferLongerCaptures.js +30 -0
- package/lib/partialMatchRegExp/regexFeatures.d.ts +6 -0
- package/lib/partialMatchRegExp/regexFeatures.js +47 -0
- package/lib/partialMatchRegExp/walk.d.ts +8 -0
- package/lib/{compilePartial.js → partialMatchRegExp/walk.js} +131 -162
- package/package.json +23 -13
- package/lib/compilePartial.d.ts +0 -26
- /package/lib/{escapeAtom.d.ts → partialMatchRegExp/escapeAtom.d.ts} +0 -0
- /package/lib/{escapeAtom.js → partialMatchRegExp/escapeAtom.js} +0 -0
|
@@ -1,66 +1,28 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { DISJUNCTION_TO_END_OF_INPUT, OPTIONAL_ATOM_OPENING } from "./atomSyntax.js";
|
|
2
|
+
import { groupNameOf, decodeGroupName } from "./groupName.js";
|
|
3
|
+
import { FEATURE_BIT } from "./regexFeatures.js";
|
|
2
4
|
const OCCURRENCES_REGEX = /\{\d+,?\d*\}/y;
|
|
3
5
|
const NOT_NUMBERS_REGEX = /\D/g;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const REGEX_FEATURES = [
|
|
10
|
-
"patternCharacter",
|
|
11
|
-
"startAnchor",
|
|
12
|
-
"endAnchor",
|
|
13
|
-
"wordBoundary",
|
|
14
|
-
"nonWordBoundary",
|
|
15
|
-
"lookahead",
|
|
16
|
-
"negativeLookahead",
|
|
17
|
-
"lookbehind",
|
|
18
|
-
"negativeLookbehind",
|
|
19
|
-
"backreference",
|
|
20
|
-
"namedBackreference",
|
|
21
|
-
"namedGroup",
|
|
22
|
-
"capturingGroup",
|
|
23
|
-
"lookaroundCapture",
|
|
24
|
-
"nonCapturingGroup",
|
|
25
|
-
"modifierGroup",
|
|
26
|
-
"modifierGroupWithRemoval",
|
|
27
|
-
"characterClass",
|
|
28
|
-
"nestedCharacterClass",
|
|
29
|
-
"classIntersection",
|
|
30
|
-
"classSubtraction",
|
|
31
|
-
"disjunction",
|
|
32
|
-
"quantifier",
|
|
33
|
-
"unicodePropertyEscape",
|
|
34
|
-
"characterClassEscape",
|
|
35
|
-
"controlEscape",
|
|
36
|
-
"controlLetterEscape",
|
|
37
|
-
"hexEscapeSequence",
|
|
38
|
-
"unicodeEscapeSequence",
|
|
39
|
-
"otherEscape"
|
|
40
|
-
];
|
|
41
|
-
const FEATURE_BIT = {};
|
|
42
|
-
for (let index = 0; index < REGEX_FEATURES.length; index++) {
|
|
43
|
-
FEATURE_BIT[REGEX_FEATURES[index]] = 1 << index;
|
|
44
|
-
}
|
|
45
|
-
function featureSet(mask) {
|
|
46
|
-
const features = new Set();
|
|
47
|
-
for (let index = 0; index < REGEX_FEATURES.length; index++) {
|
|
48
|
-
if (mask & (1 << index))
|
|
49
|
-
features.add(REGEX_FEATURES[index]);
|
|
50
|
-
}
|
|
51
|
-
return features;
|
|
52
|
-
}
|
|
53
|
-
function walk(regex) {
|
|
6
|
+
const LITERAL_K_ATOM = OPTIONAL_ATOM_OPENING + "k" + DISJUNCTION_TO_END_OF_INPUT;
|
|
7
|
+
const NO_RAW_LOOKAROUNDS = [];
|
|
8
|
+
const NO_NAMED_GROUP_OPENINGS = [];
|
|
9
|
+
const declaresGroupNamed = (closedGroupNames, name) => { var _a; return (_a = closedGroupNames === null || closedGroupNames === void 0 ? void 0 : closedGroupNames.has(decodeGroupName(name))) !== null && _a !== void 0 ? _a : false; };
|
|
10
|
+
export function walk(regex, declaresNamedGroup) {
|
|
54
11
|
const source = regex.source;
|
|
55
12
|
const isUnicode = regex.unicode || regex.unicodeSets;
|
|
56
13
|
let i = 0;
|
|
57
14
|
let groupCount = 0;
|
|
58
15
|
let featureMask = 0;
|
|
16
|
+
let rawLookarounds;
|
|
17
|
+
let namedGroupOpenings;
|
|
18
|
+
let closedGroupNumbers;
|
|
19
|
+
let closedGroupNames;
|
|
20
|
+
let namedBackreferencesSeen;
|
|
21
|
+
let currentRawLookaroundBackreferences;
|
|
59
22
|
function extractSlice(length) {
|
|
60
23
|
return source.slice(i, (i += length));
|
|
61
24
|
}
|
|
62
|
-
function process(withinLookaround) {
|
|
63
|
-
var _a;
|
|
25
|
+
function process(withinLookaround, declaresNamedGroup, caseInsensitive) {
|
|
64
26
|
const result = [];
|
|
65
27
|
function appendOptional(length) {
|
|
66
28
|
result.push("(?:" + extractSlice(length) + DISJUNCTION_TO_END_OF_INPUT);
|
|
@@ -68,10 +30,41 @@ function walk(regex) {
|
|
|
68
30
|
function appendRaw(length) {
|
|
69
31
|
result.push(extractSlice(length));
|
|
70
32
|
}
|
|
33
|
+
function appendDigitRun(forcedRef) {
|
|
34
|
+
featureMask |= FEATURE_BIT.backreference;
|
|
35
|
+
NOT_NUMBERS_REGEX.lastIndex = i + 1;
|
|
36
|
+
const nextNonDigit = NOT_NUMBERS_REGEX.exec(source);
|
|
37
|
+
const start = i;
|
|
38
|
+
const end = nextNonDigit ? nextNonDigit.index : source.length;
|
|
39
|
+
const ref = forcedRef !== null && forcedRef !== void 0 ? forcedRef : Number(source.slice(start + 1, end));
|
|
40
|
+
i = end;
|
|
41
|
+
const backreference = {
|
|
42
|
+
ref,
|
|
43
|
+
start,
|
|
44
|
+
end,
|
|
45
|
+
forward: !(closedGroupNumbers === null || closedGroupNumbers === void 0 ? void 0 : closedGroupNumbers.has(ref)),
|
|
46
|
+
caseInsensitive
|
|
47
|
+
};
|
|
48
|
+
result.push(backreference);
|
|
49
|
+
currentRawLookaroundBackreferences === null || currentRawLookaroundBackreferences === void 0 ? void 0 : currentRawLookaroundBackreferences.push(backreference);
|
|
50
|
+
}
|
|
71
51
|
function appendRawLookaround(prefixLength) {
|
|
72
52
|
const start = i;
|
|
73
53
|
i += prefixLength;
|
|
74
|
-
|
|
54
|
+
const groupCountBefore = groupCount;
|
|
55
|
+
const isOutermost = currentRawLookaroundBackreferences === undefined;
|
|
56
|
+
const backreferences = currentRawLookaroundBackreferences !== null && currentRawLookaroundBackreferences !== void 0 ? currentRawLookaroundBackreferences : [];
|
|
57
|
+
if (isOutermost)
|
|
58
|
+
currentRawLookaroundBackreferences = backreferences;
|
|
59
|
+
process(true, declaresNamedGroup, caseInsensitive);
|
|
60
|
+
if (isOutermost) {
|
|
61
|
+
(rawLookarounds !== null && rawLookarounds !== void 0 ? rawLookarounds : (rawLookarounds = [])).push({
|
|
62
|
+
sourceStart: start,
|
|
63
|
+
capturingGroupsOpened: groupCount - groupCountBefore,
|
|
64
|
+
backreferences
|
|
65
|
+
});
|
|
66
|
+
currentRawLookaroundBackreferences = undefined;
|
|
67
|
+
}
|
|
75
68
|
result.push(source.slice(start, i));
|
|
76
69
|
}
|
|
77
70
|
while (i < source.length) {
|
|
@@ -84,15 +77,35 @@ function walk(regex) {
|
|
|
84
77
|
break;
|
|
85
78
|
case "k": {
|
|
86
79
|
const referenceEnd = source[i + 2] === "<" ? source.indexOf(">", i) : -1;
|
|
87
|
-
if (referenceEnd
|
|
88
|
-
appendOptional(2);
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
80
|
+
if (referenceEnd !== -1 && declaresNamedGroup) {
|
|
91
81
|
featureMask |= FEATURE_BIT.namedBackreference;
|
|
92
82
|
const start = i;
|
|
93
83
|
const ref = source.slice(i + 3, referenceEnd);
|
|
94
84
|
i = referenceEnd + 1;
|
|
95
|
-
|
|
85
|
+
const namedBackreference = {
|
|
86
|
+
ref,
|
|
87
|
+
start,
|
|
88
|
+
end: i,
|
|
89
|
+
forward: !declaresGroupNamed(closedGroupNames, ref),
|
|
90
|
+
caseInsensitive
|
|
91
|
+
};
|
|
92
|
+
result.push(namedBackreference);
|
|
93
|
+
currentRawLookaroundBackreferences === null || currentRawLookaroundBackreferences === void 0 ? void 0 : currentRawLookaroundBackreferences.push(namedBackreference);
|
|
94
|
+
(namedBackreferencesSeen !== null && namedBackreferencesSeen !== void 0 ? namedBackreferencesSeen : (namedBackreferencesSeen = [])).push(namedBackreference);
|
|
95
|
+
}
|
|
96
|
+
else if (currentRawLookaroundBackreferences) {
|
|
97
|
+
const start = i;
|
|
98
|
+
i += 2;
|
|
99
|
+
currentRawLookaroundBackreferences.push({
|
|
100
|
+
ref: "",
|
|
101
|
+
start,
|
|
102
|
+
end: i,
|
|
103
|
+
caseInsensitive
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
result.push(LITERAL_K_ATOM);
|
|
108
|
+
i += 2;
|
|
96
109
|
}
|
|
97
110
|
break;
|
|
98
111
|
}
|
|
@@ -135,6 +148,15 @@ function walk(regex) {
|
|
|
135
148
|
featureMask |= FEATURE_BIT.controlEscape;
|
|
136
149
|
appendOptional(2);
|
|
137
150
|
break;
|
|
151
|
+
case "0":
|
|
152
|
+
if (isUnicode) {
|
|
153
|
+
featureMask |= FEATURE_BIT.otherEscape;
|
|
154
|
+
appendOptional(2);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
appendDigitRun(0);
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
138
160
|
case "1":
|
|
139
161
|
case "2":
|
|
140
162
|
case "3":
|
|
@@ -143,17 +165,9 @@ function walk(regex) {
|
|
|
143
165
|
case "6":
|
|
144
166
|
case "7":
|
|
145
167
|
case "8":
|
|
146
|
-
case "9":
|
|
147
|
-
|
|
148
|
-
NOT_NUMBERS_REGEX.lastIndex = i + 1;
|
|
149
|
-
const nextNonDigit = NOT_NUMBERS_REGEX.exec(source);
|
|
150
|
-
const start = i;
|
|
151
|
-
const end = nextNonDigit ? nextNonDigit.index : source.length;
|
|
152
|
-
const ref = Number(source.slice(start + 1, end));
|
|
153
|
-
i = end;
|
|
154
|
-
result.push({ ref, start, end });
|
|
168
|
+
case "9":
|
|
169
|
+
appendDigitRun();
|
|
155
170
|
break;
|
|
156
|
-
}
|
|
157
171
|
case "d":
|
|
158
172
|
case "D":
|
|
159
173
|
case "w":
|
|
@@ -242,13 +256,13 @@ function walk(regex) {
|
|
|
242
256
|
featureMask |= FEATURE_BIT.nonCapturingGroup;
|
|
243
257
|
result.push("(?:");
|
|
244
258
|
i += 3;
|
|
245
|
-
result.push(...process(withinLookaround), DISJUNCTION_TO_END_OF_INPUT);
|
|
259
|
+
result.push(...process(withinLookaround, declaresNamedGroup, caseInsensitive), DISJUNCTION_TO_END_OF_INPUT);
|
|
246
260
|
break;
|
|
247
261
|
case "=":
|
|
248
262
|
featureMask |= FEATURE_BIT.lookahead;
|
|
249
263
|
result.push("(?=");
|
|
250
264
|
i += 3;
|
|
251
|
-
result.push(...process(true), ")");
|
|
265
|
+
result.push(...process(true, declaresNamedGroup, caseInsensitive), ")");
|
|
252
266
|
break;
|
|
253
267
|
case "-":
|
|
254
268
|
case "i":
|
|
@@ -256,12 +270,16 @@ function walk(regex) {
|
|
|
256
270
|
case "m": {
|
|
257
271
|
const flagsStart = i + 2, colonIndex = source.indexOf(":", flagsStart);
|
|
258
272
|
const modifiers = source.slice(flagsStart, colonIndex);
|
|
259
|
-
|
|
273
|
+
const [additions, removals] = modifiers.split("-");
|
|
274
|
+
featureMask |= removals
|
|
260
275
|
? FEATURE_BIT.modifierGroupWithRemoval
|
|
261
276
|
: FEATURE_BIT.modifierGroup;
|
|
277
|
+
const modifierGroupCaseInsensitive = (removals === null || removals === void 0 ? void 0 : removals.includes("i"))
|
|
278
|
+
? false
|
|
279
|
+
: caseInsensitive || additions.includes("i");
|
|
262
280
|
result.push("(?" + modifiers + ":");
|
|
263
281
|
i = colonIndex + 1;
|
|
264
|
-
result.push(...process(withinLookaround), ")");
|
|
282
|
+
result.push(...process(withinLookaround, declaresNamedGroup, modifierGroupCaseInsensitive), ")");
|
|
265
283
|
break;
|
|
266
284
|
}
|
|
267
285
|
case "!":
|
|
@@ -278,15 +296,21 @@ function walk(regex) {
|
|
|
278
296
|
featureMask |= FEATURE_BIT.negativeLookbehind;
|
|
279
297
|
appendRawLookaround(4);
|
|
280
298
|
break;
|
|
281
|
-
default:
|
|
299
|
+
default: {
|
|
282
300
|
featureMask |= FEATURE_BIT.namedGroup;
|
|
283
301
|
featureMask |= FEATURE_BIT.capturingGroup;
|
|
284
302
|
if (withinLookaround)
|
|
285
303
|
featureMask |= FEATURE_BIT.lookaroundCapture;
|
|
286
|
-
++groupCount;
|
|
287
|
-
|
|
288
|
-
|
|
304
|
+
const groupNumber = ++groupCount;
|
|
305
|
+
const opening = extractSlice(source.indexOf(">", i) - i + 1);
|
|
306
|
+
(namedGroupOpenings !== null && namedGroupOpenings !== void 0 ? namedGroupOpenings : (namedGroupOpenings = [])).push(opening);
|
|
307
|
+
const declaredName = decodeGroupName(groupNameOf(opening));
|
|
308
|
+
result.push(opening);
|
|
309
|
+
result.push(...process(withinLookaround, declaresNamedGroup, caseInsensitive), DISJUNCTION_TO_END_OF_INPUT);
|
|
310
|
+
(closedGroupNumbers !== null && closedGroupNumbers !== void 0 ? closedGroupNumbers : (closedGroupNumbers = new Set())).add(groupNumber);
|
|
311
|
+
(closedGroupNames !== null && closedGroupNames !== void 0 ? closedGroupNames : (closedGroupNames = new Set())).add(declaredName);
|
|
289
312
|
break;
|
|
313
|
+
}
|
|
290
314
|
}
|
|
291
315
|
break;
|
|
292
316
|
}
|
|
@@ -295,9 +319,10 @@ function walk(regex) {
|
|
|
295
319
|
featureMask |= FEATURE_BIT.capturingGroup;
|
|
296
320
|
if (withinLookaround)
|
|
297
321
|
featureMask |= FEATURE_BIT.lookaroundCapture;
|
|
298
|
-
++groupCount;
|
|
322
|
+
const groupNumber = ++groupCount;
|
|
299
323
|
appendRaw(1);
|
|
300
|
-
result.push(...process(withinLookaround), DISJUNCTION_TO_END_OF_INPUT);
|
|
324
|
+
result.push(...process(withinLookaround, declaresNamedGroup, caseInsensitive), DISJUNCTION_TO_END_OF_INPUT);
|
|
325
|
+
(closedGroupNumbers !== null && closedGroupNumbers !== void 0 ? closedGroupNumbers : (closedGroupNumbers = new Set())).add(groupNumber);
|
|
301
326
|
}
|
|
302
327
|
break;
|
|
303
328
|
case ")":
|
|
@@ -305,93 +330,37 @@ function walk(regex) {
|
|
|
305
330
|
return result;
|
|
306
331
|
default:
|
|
307
332
|
featureMask |= FEATURE_BIT.patternCharacter;
|
|
308
|
-
|
|
333
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- i < source.length is the loop invariant, so codePointAt(i) is always defined
|
|
334
|
+
appendOptional(isUnicode && source.codePointAt(i) > 0xffff ? 2 : 1);
|
|
309
335
|
break;
|
|
310
336
|
}
|
|
311
337
|
}
|
|
312
338
|
return result;
|
|
313
339
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
}
|
|
333
|
-
function spliceOriginalSource(source, backrefs) {
|
|
334
|
-
let result = "";
|
|
335
|
-
let cursor = 0;
|
|
336
|
-
for (const { start, end } of backrefs) {
|
|
337
|
-
result += source.slice(cursor, start) + ANY_CAPTURED_TEXT;
|
|
338
|
-
cursor = end;
|
|
339
|
-
}
|
|
340
|
-
return result + source.slice(cursor);
|
|
341
|
-
}
|
|
342
|
-
function expandCaptured(value, isUnicode) {
|
|
343
|
-
return (isUnicode ? Array.from(value) : value.split(""))
|
|
344
|
-
.map((atom) => "(?:" + escapeAtom(atom) + DISJUNCTION_TO_END_OF_INPUT)
|
|
345
|
-
.join("");
|
|
346
|
-
}
|
|
347
|
-
class Compiled {
|
|
348
|
-
constructor(_featureMask) {
|
|
349
|
-
this._featureMask = _featureMask;
|
|
350
|
-
}
|
|
351
|
-
get features() {
|
|
352
|
-
var _a;
|
|
353
|
-
return ((_a = this._features) !== null && _a !== void 0 ? _a : (this._features = featureSet(this._featureMask)));
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
class CompiledStatic extends Compiled {
|
|
357
|
-
constructor(regex, featureMask) {
|
|
358
|
-
super(featureMask);
|
|
359
|
-
this.regex = regex;
|
|
360
|
-
this.kind = "static";
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
class CompiledDynamic extends Compiled {
|
|
364
|
-
constructor(dynamic, featureMask) {
|
|
365
|
-
super(featureMask);
|
|
366
|
-
this.dynamic = dynamic;
|
|
367
|
-
this.kind = "dynamic";
|
|
340
|
+
const parts = process(false, declaresNamedGroup, regex.flags.includes("i"));
|
|
341
|
+
if (namedGroupOpenings && namedBackreferencesSeen) {
|
|
342
|
+
const seenOnce = new Set();
|
|
343
|
+
let duplicated;
|
|
344
|
+
for (const opening of namedGroupOpenings) {
|
|
345
|
+
const name = decodeGroupName(groupNameOf(opening));
|
|
346
|
+
if (seenOnce.has(name))
|
|
347
|
+
(duplicated !== null && duplicated !== void 0 ? duplicated : (duplicated = new Set())).add(name);
|
|
348
|
+
else
|
|
349
|
+
seenOnce.add(name);
|
|
350
|
+
}
|
|
351
|
+
if (duplicated) {
|
|
352
|
+
for (const backreference of namedBackreferencesSeen) {
|
|
353
|
+
if (duplicated.has(decodeGroupName(backreference.ref))) {
|
|
354
|
+
backreference.forward = true;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
368
358
|
}
|
|
359
|
+
return {
|
|
360
|
+
parts,
|
|
361
|
+
groupCount,
|
|
362
|
+
featureMask,
|
|
363
|
+
rawLookarounds: rawLookarounds !== null && rawLookarounds !== void 0 ? rawLookarounds : NO_RAW_LOOKAROUNDS,
|
|
364
|
+
namedGroupOpenings: namedGroupOpenings !== null && namedGroupOpenings !== void 0 ? namedGroupOpenings : NO_NAMED_GROUP_OPENINGS
|
|
365
|
+
};
|
|
369
366
|
}
|
|
370
|
-
export const compilePartial = (regex) => {
|
|
371
|
-
const { parts, groupCount, featureMask } = walk(regex);
|
|
372
|
-
const flags = regex.flags;
|
|
373
|
-
if (!MAYBE_HAS_BACKREFERENCE_REGEX.test(regex.source)) {
|
|
374
|
-
return new CompiledStatic(new RegExp(render(parts, backrefToken), flags), featureMask);
|
|
375
|
-
}
|
|
376
|
-
const isUnicode = regex.unicode || regex.unicodeSets;
|
|
377
|
-
const sanitisedParts = isUnicode
|
|
378
|
-
? parts
|
|
379
|
-
: reclassifyOctalEscapes(parts, regex.source, groupCount);
|
|
380
|
-
const backreferences = sanitisedParts.filter(isBackreference);
|
|
381
|
-
if (backreferences.length === 0) {
|
|
382
|
-
return new CompiledStatic(new RegExp(render(sanitisedParts, backrefToken), flags), featureMask);
|
|
383
|
-
}
|
|
384
|
-
return new CompiledDynamic({
|
|
385
|
-
originalCaptureScan: new RegExp(spliceOriginalSource(regex.source, backreferences), flags),
|
|
386
|
-
preScan: new RegExp(render(parts, () => ANY_CAPTURED_TEXT), flags),
|
|
387
|
-
expand: (capture) => render(parts, (backref) => {
|
|
388
|
-
var _a;
|
|
389
|
-
const captured = isNumericBackreference(backref)
|
|
390
|
-
? capture[backref.ref]
|
|
391
|
-
: (_a = capture.groups) === null || _a === void 0 ? void 0 : _a[backref.ref];
|
|
392
|
-
return captured === undefined
|
|
393
|
-
? "(?:" + backrefToken(backref) + DISJUNCTION_TO_END_OF_INPUT
|
|
394
|
-
: expandCaptured(captured, isUnicode);
|
|
395
|
-
})
|
|
396
|
-
}, featureMask);
|
|
397
|
-
};
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "regex-partial-match",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "A regular expression transform for partial matching",
|
|
5
5
|
"devEngines": {
|
|
6
6
|
"runtime": {
|
|
7
7
|
"name": "node",
|
|
8
|
-
"version": ">=
|
|
8
|
+
"version": ">=24.12"
|
|
9
9
|
},
|
|
10
10
|
"packageManager": {
|
|
11
11
|
"name": "npm",
|
|
12
|
-
"version": "11.
|
|
12
|
+
"version": "11.19.0+sha512.48377f8478372aa1c4e47b763475b135836da82436a5700f2e5e8eb5084fc840f93c7b117eb3ad3b5f7d3194c81b6710a10d59448f6ddbcb21ac3fb672bdc003"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
@@ -33,17 +33,22 @@
|
|
|
33
33
|
}
|
|
34
34
|
],
|
|
35
35
|
"type": "module",
|
|
36
|
-
"main": "lib/partialMatchRegExp.js",
|
|
36
|
+
"main": "lib/partialMatchRegExp/index.js",
|
|
37
37
|
"exports": {
|
|
38
38
|
".": {
|
|
39
|
-
"types": "./lib/partialMatchRegExp.d.ts",
|
|
40
|
-
"import": "./lib/partialMatchRegExp.js",
|
|
41
|
-
"default": "./lib/partialMatchRegExp.js"
|
|
39
|
+
"types": "./lib/partialMatchRegExp/index.d.ts",
|
|
40
|
+
"import": "./lib/partialMatchRegExp/index.js",
|
|
41
|
+
"default": "./lib/partialMatchRegExp/index.js"
|
|
42
42
|
},
|
|
43
43
|
"./extend": {
|
|
44
|
-
"types": "./lib/extend.d.ts",
|
|
45
|
-
"import": "./lib/extend.js",
|
|
46
|
-
"default": "./lib/extend.js"
|
|
44
|
+
"types": "./lib/extend/index.d.ts",
|
|
45
|
+
"import": "./lib/extend/index.js",
|
|
46
|
+
"default": "./lib/extend/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./partialMatchRegExp": {
|
|
49
|
+
"types": "./lib/partialMatchRegExp/partialMatchRegExp.d.ts",
|
|
50
|
+
"import": "./lib/partialMatchRegExp/partialMatchRegExp.js",
|
|
51
|
+
"default": "./lib/partialMatchRegExp/partialMatchRegExp.js"
|
|
47
52
|
}
|
|
48
53
|
},
|
|
49
54
|
"files": [
|
|
@@ -54,9 +59,11 @@
|
|
|
54
59
|
"url": "git+https://github.com/TomStrepsil/regex-partial-match.git"
|
|
55
60
|
},
|
|
56
61
|
"workspaces": [
|
|
57
|
-
"benchmarking"
|
|
62
|
+
"test/benchmarking"
|
|
63
|
+
],
|
|
64
|
+
"sideEffects": [
|
|
65
|
+
"./lib/extend/index.js"
|
|
58
66
|
],
|
|
59
|
-
"sideEffects": false,
|
|
60
67
|
"scripts": {
|
|
61
68
|
"lint": "eslint .",
|
|
62
69
|
"lint:fix": "eslint . --fix",
|
|
@@ -64,7 +71,8 @@
|
|
|
64
71
|
"prepublishOnly": "tsc -p tsconfig.build.json",
|
|
65
72
|
"ci:smoke-test-built-package": "node .github/scripts/smoke-test-built-package.ts",
|
|
66
73
|
"test": "vitest run --config ./test/vitest.config.ts",
|
|
67
|
-
"test:watch": "vitest --config ./test/vitest.config.ts"
|
|
74
|
+
"test:watch": "vitest --config ./test/vitest.config.ts",
|
|
75
|
+
"test:coverage": "vitest run --config ./test/vitest.config.ts --coverage"
|
|
68
76
|
},
|
|
69
77
|
"simple-git-hooks": {
|
|
70
78
|
"pre-commit": "node_modules/.bin/lint-staged"
|
|
@@ -83,6 +91,8 @@
|
|
|
83
91
|
"@types/node": "^25.9.3",
|
|
84
92
|
"@typescript/lib-es2018": "file:types/lib-es2018",
|
|
85
93
|
"@typescript/lib-es2022": "file:types/lib-es2022",
|
|
94
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
95
|
+
"esbuild": "^0.28.1",
|
|
86
96
|
"eslint": "^9.17.0",
|
|
87
97
|
"jiti": "^2.6.1",
|
|
88
98
|
"lint-staged": "^15.2.11",
|
package/lib/compilePartial.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
declare const REGEX_FEATURES: readonly ["patternCharacter", "startAnchor", "endAnchor", "wordBoundary", "nonWordBoundary", "lookahead", "negativeLookahead", "lookbehind", "negativeLookbehind", "backreference", "namedBackreference", "namedGroup", "capturingGroup", "lookaroundCapture", "nonCapturingGroup", "modifierGroup", "modifierGroupWithRemoval", "characterClass", "nestedCharacterClass", "classIntersection", "classSubtraction", "disjunction", "quantifier", "unicodePropertyEscape", "characterClassEscape", "controlEscape", "controlLetterEscape", "hexEscapeSequence", "unicodeEscapeSequence", "otherEscape"];
|
|
2
|
-
export type RegexFeature = (typeof REGEX_FEATURES)[number];
|
|
3
|
-
export interface DynamicPath {
|
|
4
|
-
originalCaptureScan: RegExp;
|
|
5
|
-
preScan: RegExp;
|
|
6
|
-
expand: (capture: RegExpExecArray) => string;
|
|
7
|
-
}
|
|
8
|
-
declare abstract class Compiled {
|
|
9
|
-
private readonly _featureMask;
|
|
10
|
-
private _features?;
|
|
11
|
-
constructor(_featureMask: number);
|
|
12
|
-
get features(): ReadonlySet<RegexFeature>;
|
|
13
|
-
}
|
|
14
|
-
declare class CompiledStatic extends Compiled {
|
|
15
|
-
readonly regex: RegExp;
|
|
16
|
-
readonly kind = "static";
|
|
17
|
-
constructor(regex: RegExp, featureMask: number);
|
|
18
|
-
}
|
|
19
|
-
declare class CompiledDynamic extends Compiled {
|
|
20
|
-
readonly dynamic: DynamicPath;
|
|
21
|
-
readonly kind = "dynamic";
|
|
22
|
-
constructor(dynamic: DynamicPath, featureMask: number);
|
|
23
|
-
}
|
|
24
|
-
export type CompiledPartial = CompiledStatic | CompiledDynamic;
|
|
25
|
-
export declare const compilePartial: (regex: RegExp) => CompiledPartial;
|
|
26
|
-
export {};
|
|
File without changes
|
|
File without changes
|