regex-partial-match 0.1.7 → 0.1.10

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 CHANGED
@@ -77,7 +77,8 @@ Such combinations have not been tested.
77
77
  - 👥 [Groups](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Capturing_group) (capturing and non-capturing) (`(?:abc)`, `(abc)`, `(?<named>abc)`)
78
78
  - 👀 [Lookahead assertions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Lookahead_assertion) (`(?=...)`, `(?!...)`)
79
79
  - 👈 [Lookbehind assertions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Lookbehind_assertion) (`(?<=...)`, `(?<!...)`)
80
- - ⚓ [Anchors](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Input_boundary_assertion) (`^`, `$`)
80
+ - ⚓ [Input Boundaries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Input_boundary_assertion) (`^`, `$`)
81
+ - 🆒 [Word Boundaries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Word_boundary_assertion) (`\b`, `\B`)
81
82
  - 🏴 [Flags](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags): `g`, `i`, `m`, `s`, `u`, `d`, `y` (See caveats for `y`)
82
83
 
83
84
  ## Unsupported Features
@@ -85,8 +86,8 @@ Such combinations have not been tested.
85
86
  The following regex features are **not currently supported**:
86
87
 
87
88
  - ⚠️ [Backreferences](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Backreference) (`\1`, `\k<name>`) - Can be included, but can't partially match. See [caveats](#caveats).
88
- - ❌ [Unicode sets (`v` flag)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicodeSets) - ES2024+
89
- - ❌ [Modifiers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Modifier) (`(?ims:...)`, `(?-ims:...)`) - ES2025+
89
+ - ❌ [Unicode sets (`v` flag)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicodeSets) - ES2024+. See [issue](https://github.com/TomStrepsil/regex-partial-match/issues/1).
90
+ - ❌ [Modifiers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Modifier) (`(?ims:...)`, `(?-ims:...)`) - ES2025+. See [issue](https://github.com/TomStrepsil/regex-partial-match/issues/2).
90
91
 
91
92
  ## Browser Compatibility
92
93
 
@@ -101,15 +102,57 @@ The library is compiled to **ES5** for broad compatibility with older browsers a
101
102
 
102
103
  ## Caveats
103
104
 
105
+ ### [`.test()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) behaviour and non-matching results from [`.exec()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec) and [`.match()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match)
106
+
107
+ The library produces an expression that always matches an empty string, at the end of the input. Feasibly, this is the start of a new partial match.
108
+
109
+ Hence:
110
+
111
+ ```js
112
+ /x/.test("a") === false; /* untransformed regex */
113
+ /(?:x|$)/.test("a") === true; /* what's produced by the library */
114
+ ```
115
+
116
+ To mitigate, a start boundary anchor can prevent anything _but_ an empty string matching:
117
+
118
+ ```js
119
+ /^(?:x|$)/.test("") === true;
120
+ /^(?:x|$)/.test("x") === true;
121
+ /^(?:x|$)/.test("a") === false;
122
+ ```
123
+
124
+ On this basis, `.test()` should be used with caution, and a match of an empty string at the end of the input should instead be considered "no match", if validating that which came before.
125
+
126
+ i.e.
127
+
128
+ ```js
129
+ /(?:x|$)/.exec("a"); // ['', index: 1, input: "a", groups: undefined];
130
+ "a".match(/(?:x|$)/); // ['', index: 1, input: "a", groups: undefined];
131
+ ```
132
+
133
+ Since the library produces a native `RegExp` object, no attempt to proxy / translate this output to `null` has been attempted, but a helper could be produced in future, for clarity. See [issue](https://github.com/TomStrepsil/regex-partial-match/issues/14).
134
+
104
135
  ### Backreferences
105
136
 
106
137
  **Backreferences cannot be partially matched because they are atomic.** A backreference like `\1` must match the complete captured text or fail entirely, and cannot be split into individual characters for partial matching like regular atoms can.
107
138
 
108
139
  Fixed-length patterns like `/(abc)\1/` could theoretically become `/(?:(a)|$)(?:(b)|$)(?:(c)|$)(?:\1|$)(?:\2|$)(?:\3|$)/` (accepting polluted capture indexes as a side-effect), but this doesn't work for variable-length captures.
109
140
 
141
+ ### Positive Lookbehinds
142
+
143
+ Whilst forming a match, a positive lookbehind must match in entirety, for the pattern to match. This is inherent in the concept of non-matching groups, since they are not match-worthy themselves, but just qualify matching atoms.
144
+
145
+ e.g.
146
+
147
+ ```js
148
+ /(?<=foo)bar/;
149
+ ```
150
+
151
+ "f" through "foo" is not a match, but "foob" is.
152
+
110
153
  ### Surrogate Pair Matching
111
154
 
112
- In unicode-aware mode (`u` flag), **only whole astral characters are supported**. Partial matching of individual surrogate pairs is not supported. For example, `/😀/u` will match the complete emoji character, but not the first surrogate pair in isolation. Hence, if partially matching a byte stream, be sure to pipe via a [`TextDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder) first.
155
+ In [unicode-aware mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode) (`u` flag), **only whole astral characters are supported**. Partial matching of individual surrogate pairs is not supported. For example, `/😀/u` will match the complete emoji character, but not the first surrogate pair in isolation. Hence, if partially matching a byte stream, be sure to pipe via a [`TextDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder) first.
113
156
 
114
157
  ### [Sticky](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky) Flag (`y`)
115
158
 
@@ -140,8 +183,6 @@ The global flag does not cause issues like the sticky flag, as partial patterns
140
183
  ### Form Validation
141
184
 
142
185
  ```javascript
143
- import createPartialMatchRegex from "regex-partial-match";
144
-
145
186
  const emailPattern = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i;
146
187
  const partial = createPartialMatchRegex(emailPattern);
147
188
 
@@ -175,8 +216,6 @@ getSuggestions("xyz"); // 'no suggestions'
175
216
  ### Stream Processing
176
217
 
177
218
  ```javascript
178
- import createPartialMatchRegex from "regex-partial-match";
179
-
180
219
  // Process streaming data with pattern matching at chunk boundaries
181
220
  const pattern = /\{"[^"]+":"[^"]+"\}/; // Match JSON objects
182
221
  const partial = createPartialMatchRegex(pattern);
@@ -246,11 +285,13 @@ Algorithm created by [Lucas Trzesniewski](https://github.com/ltrzesniewski).
246
285
 
247
286
  Contributions are welcome! Please open an issue or pull request on [GitHub](https://github.com/TomStrepsil/regex-partial-match).
248
287
 
249
- ## Related packages
288
+ ## Related projects
250
289
 
251
- - [`incr-regex-package`](https://www.npmjs.com/package/incr-regex-package)
252
- - Incremental regex matcher
253
- - [`dfa`](https://github.com/foliojs/dfa)
254
- - Compiles a regular expression like syntax to fast deterministic finite automata, which could be used to partial match?
255
- - [`refa`](https://github.com/RunDevelopment/refa)
256
- - Can [convert regular expressions to an Abstract Syntax Tree](https://rundevelopment.github.io/refa/docs/latest/classes/JS.Parser.html), which might afford partial-match capability?
290
+ | Project | Description |
291
+ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
292
+ | [`incr-regex-package`](https://www.npmjs.com/package/incr-regex-package) | Incremental regex matcher |
293
+ | [`dfa`](https://github.com/foliojs/dfa) | Compiles a regular expression like syntax to fast deterministic finite automata, which could be used to partial match? |
294
+ | [`refa`](https://github.com/RunDevelopment/refa) | Can [convert regular expressions to an Abstract Syntax Tree](https://rundevelopment.github.io/refa/docs/latest/classes/JS.Parser.html), which might afford partial-match capability? |
295
+ | [`@eslint-community/regexpp`](https://github.com/eslint-community/regexpp) | A regular expression parser for ECMAScript with AST generation and visitor implementation |
296
+ | [`Regex+`](https://www.npmjs.com/package/regex) | template literal, transforming native regular expressions |
297
+ | [`Awesome Regex`](https://github.com/slevithan/awesome-regex) | Curated list of tools, tutorials, libraries, and other resources, covering all major regex flavours |
package/lib/extend.d.ts CHANGED
@@ -1,5 +1,34 @@
1
1
  declare global {
2
2
  interface RegExp {
3
+ /**
4
+ * Transforms this regular expression to support partial matching.
5
+ *
6
+ * This method wraps each atomic element of the regex pattern in a non-capturing group
7
+ * with an alternation to end-of-input (`$`), allowing the pattern to match prefixes
8
+ * of the original pattern. This enables validation of incomplete input strings.
9
+ *
10
+ * @returns A new RegExp that matches partial strings of the original pattern
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import 'regex-partial-match/extend';
15
+ *
16
+ * const partial = /hello world/.toPartialMatchRegex();
17
+ *
18
+ * partial.test('h'); // true - could match
19
+ * partial.test('hello'); // true - could match
20
+ * partial.test('hello world'); // true - full match
21
+ * partial.test('goodbye'); // false - cannot match
22
+ * ```
23
+ *
24
+ * @remarks
25
+ * - The transformed regex will always match an empty string at the end of input
26
+ * - Backreferences cannot be partially matched as they are atomic
27
+ * - Use with a start anchor (`^`) to prevent false positives from empty string matches
28
+ * - The `y` (sticky) flag may not behave as expected in partial matching scenarios
29
+ *
30
+ * @see {@link https://github.com/TomStrepsil/regex-partial-match#readme | Documentation}
31
+ */
3
32
  toPartialMatchRegex(): RegExp;
4
33
  }
5
34
  }
package/lib/index.d.ts CHANGED
@@ -1,2 +1,31 @@
1
1
  declare const createPartialMatchRegex: (regex: RegExp) => RegExp;
2
+ /**
3
+ * Transforms a regular expression to support partial matching.
4
+ *
5
+ * This function wraps each atomic element of the regex pattern in a non-capturing group
6
+ * with an alternation to end-of-input (`$`), allowing the pattern to match prefixes
7
+ * of the original pattern. This enables validation of incomplete input strings.
8
+ *
9
+ * @param regex - The regular expression to transform for partial matching
10
+ * @returns A new RegExp that matches partial strings of the original pattern
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const pattern = /hello world/;
15
+ * const partial = createPartialMatchRegex(pattern);
16
+ *
17
+ * partial.test('h'); // true - could match
18
+ * partial.test('hello'); // true - could match
19
+ * partial.test('hello world'); // true - full match
20
+ * partial.test('goodbye'); // false - cannot match
21
+ * ```
22
+ *
23
+ * @remarks
24
+ * - The transformed regex will always match an empty string at the end of input
25
+ * - Backreferences cannot be partially matched as they are atomic
26
+ * - Use with a start anchor (`^`) to prevent false positives from empty string matches
27
+ * - The `y` (sticky) flag may not behave as expected in partial matching scenarios
28
+ *
29
+ * @see {@link https://github.com/TomStrepsil/regex-partial-match#readme | Documentation}
30
+ */
2
31
  export default createPartialMatchRegex;
package/lib/index.js CHANGED
@@ -130,4 +130,33 @@ var createPartialMatchRegex = function (regex) {
130
130
  }
131
131
  return new RegExp(process(), regex.flags);
132
132
  };
133
+ /**
134
+ * Transforms a regular expression to support partial matching.
135
+ *
136
+ * This function wraps each atomic element of the regex pattern in a non-capturing group
137
+ * with an alternation to end-of-input (`$`), allowing the pattern to match prefixes
138
+ * of the original pattern. This enables validation of incomplete input strings.
139
+ *
140
+ * @param regex - The regular expression to transform for partial matching
141
+ * @returns A new RegExp that matches partial strings of the original pattern
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * const pattern = /hello world/;
146
+ * const partial = createPartialMatchRegex(pattern);
147
+ *
148
+ * partial.test('h'); // true - could match
149
+ * partial.test('hello'); // true - could match
150
+ * partial.test('hello world'); // true - full match
151
+ * partial.test('goodbye'); // false - cannot match
152
+ * ```
153
+ *
154
+ * @remarks
155
+ * - The transformed regex will always match an empty string at the end of input
156
+ * - Backreferences cannot be partially matched as they are atomic
157
+ * - Use with a start anchor (`^`) to prevent false positives from empty string matches
158
+ * - The `y` (sticky) flag may not behave as expected in partial matching scenarios
159
+ *
160
+ * @see {@link https://github.com/TomStrepsil/regex-partial-match#readme | Documentation}
161
+ */
133
162
  export default createPartialMatchRegex;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "regex-partial-match",
3
- "version": "0.1.7",
3
+ "version": "0.1.10",
4
4
  "description": "A regular expression transform for partial matching",
5
5
  "engines": {
6
6
  "node": ">=23"
@@ -66,6 +66,7 @@
66
66
  },
67
67
  "devDependencies": {
68
68
  "@eslint/js": "^9.17.0",
69
+ "@eslint/markdown": "^7.5.1",
69
70
  "eslint": "^9.17.0",
70
71
  "jiti": "^2.6.1",
71
72
  "lint-staged": "^15.2.11",