Skip to content

Commit b709238

Browse files
committed
Documentation improvements
1 parent 2a64bc4 commit b709238

File tree

5 files changed

+70
-62
lines changed

5 files changed

+70
-62
lines changed

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,13 @@ Then you can do this:
115115

116116
```js
117117
// Test some Unicode scripts
118+
// Can also use the Script= prefix to match ES2018: \p{Script=Hiragana}
118119
XRegExp('^\\p{Hiragana}+$').test('ひらがな'); // -> true
119120
XRegExp('^[\\p{Latin}\\p{Common}]+$').test('Über Café.'); // -> true
120121

121-
// Test the Unicode categories L (Letter) and M (Mark)
122-
const unicodeWord = XRegExp.tag()`^\pL[\pL\pM]*$`;
122+
// Test the Unicode categories Letter and Mark
123+
// Can also use the short names \p{L} and \p{M}
124+
const unicodeWord = XRegExp.tag()`^\p{Letter}[\p{Letter}\p{Mark}]*$`;
123125
unicodeWord.test('Русский'); // -> true
124126
unicodeWord.test('日本語'); // -> true
125127
unicodeWord.test('العربية'); // -> true
@@ -129,15 +131,14 @@ By default, `\p{…}` and `\P{…}` support the Basic Multilingual Plane (i.e. c
129131

130132
```js
131133
// Using flag A to match astral code points
132-
XRegExp('^\\pS$').test('💩'); // -> false
133-
XRegExp('^\\pS$', 'A').test('💩'); // -> true
134-
XRegExp('(?A)^\\pS$').test('💩'); // -> true
134+
XRegExp('^\\p{S}$').test('💩'); // -> false
135+
XRegExp('^\\p{S}$', 'A').test('💩'); // -> true
135136
// Using surrogate pair U+D83D U+DCA9 to represent U+1F4A9 (pile of poo)
136-
XRegExp('(?A)^\\pS$').test('\uD83D\uDCA9'); // -> true
137+
XRegExp('^\\p{S}$', 'A').test('\uD83D\uDCA9'); // -> true
137138

138139
// Implicit flag A
139140
XRegExp.install('astral');
140-
XRegExp('^\\pS$').test('💩'); // -> true
141+
XRegExp('^\\p{S}$').test('💩'); // -> true
141142
```
142143

143144
Opting in to astral mode disables the use of `\p{…}` and `\P{…}` within character classes. In astral mode, use e.g. `(\pL|[0-9_])+` instead of `[\pL0-9_]+`.
@@ -168,21 +169,20 @@ Named subpatterns can be provided as strings or regex objects. A leading `^` and
168169
Provides tagged template literals that create regexes with XRegExp syntax and flags:
169170

170171
```js
171-
XRegExp.match('word', XRegExp.tag()`\w\b`);
172-
// -> 'd'
173-
174-
const h12 = /1[0-2]|0?[1-9]/;
175-
const h24 = /2[0-3]|[01][0-9]/;
176-
const hours = XRegExp.tag('x')`${h12} : | ${h24}`;
177-
const minutes = /^[0-5][0-9]$/;
178-
// Note that explicitly naming the 'minutes' group is required for named backreferences
179-
const time = XRegExp.tag('x')`^ ${hours} (?<minutes>${minutes}) $`;
172+
XRegExp.tag()`\b\w+\b`.test('word'); // -> true
180173

174+
const hours = /1[0-2]|0?[1-9]/;
175+
const minutes = /(?<minutes>[0-5][0-9])/;
176+
const time = XRegExp.tag('x')`\b ${hours} : ${minutes} \b`;
181177
time.test('10:59'); // -> true
182178
XRegExp.exec('10:59', time).groups.minutes; // -> '59'
179+
180+
const backref1 = /(a)\1/;
181+
const backref2 = /(b)\1/;
182+
XRegExp.tag()`${backref1}${backref2}`.test('aabb'); // -> true
183183
```
184184

185-
`XRegExp.tag` does more than just basic interpolation. For starters, you get all the XRegExp syntax and flags. Even better, since `XRegExp.tag` uses your pattern as a raw string, you no longer need to escape all your backslashes. And since it relies on `XRegExp.build` under the hood, you get all of its extras for free. Leading `^` and trailing unescaped `$` are stripped from interpolated patterns if both are present (to allow embedding independently useful anchored regexes), interpolating into a character class is an error (to avoid unintended meaning in edge cases), interpolated patterns are treated as atomic units when quantified, interpolated strings have their special characters escaped, and any backreferences within an interpolated regex are rewritten to work within the overall pattern.
185+
`XRegExp.tag` does more than just interpolation. You get all the XRegExp syntax and flags, and since it reads patterns as raw strings, you no longer need to escape all your backslashes. `XRegExp.tag` also uses `XRegExp.build` under the hood, so you get all of its extras for free. Leading `^` and trailing unescaped `$` are stripped from interpolated patterns if both are present (to allow embedding independently useful anchored regexes), interpolating into a character class is an error (to avoid unintended meaning in edge cases), interpolated patterns are treated as atomic units when quantified, interpolated strings have their special characters escaped, and any backreferences within an interpolated regex are rewritten to work within the overall pattern.
186186

187187
### XRegExp.matchRecursive
188188

src/addons/build.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,17 @@ export default (XRegExp) => {
8787
* @returns {Function} Handler for template literals that construct regexes with XRegExp syntax.
8888
* @example
8989
*
90-
* const h12 = /1[0-2]|0?[1-9]/;
91-
* const h24 = /2[0-3]|[01][0-9]/;
92-
* const hours = XRegExp.tag('x')`${h12} : | ${h24}`;
93-
* const minutes = /^[0-5][0-9]$/;
94-
* // Note that explicitly naming the 'minutes' group is required for named backreferences
95-
* const time = XRegExp.tag('x')`^ ${hours} (?<minutes>${minutes}) $`;
90+
* XRegExp.tag()`\b\w+\b`.test('word'); // -> true
91+
*
92+
* const hours = /1[0-2]|0?[1-9]/;
93+
* const minutes = /(?<minutes>[0-5][0-9])/;
94+
* const time = XRegExp.tag('x')`\b ${hours} : ${minutes} \b`;
9695
* time.test('10:59'); // -> true
97-
* XRegExp.exec('10:59', time).minutes; // -> '59'
96+
* XRegExp.exec('10:59', time).groups.minutes; // -> '59'
97+
*
98+
* const backref1 = /(a)\1/;
99+
* const backref2 = /(b)\1/;
100+
* XRegExp.tag()`${backref1}${backref2}`.test('aabb'); // -> true
98101
*/
99102
XRegExp.tag = (flags) => (literals, ...substitutions) => {
100103
const subpatterns = substitutions.map(interpolate).reduce(reduceToSubpatternsObject, {});
@@ -125,7 +128,7 @@ export default (XRegExp) => {
125128
* minutes: /^[0-5][0-9]$/
126129
* });
127130
* time.test('10:59'); // -> true
128-
* XRegExp.exec('10:59', time).minutes; // -> '59'
131+
* XRegExp.exec('10:59', time).groups.minutes; // -> '59'
129132
*/
130133
XRegExp.build = (pattern, subs, flags) => {
131134
flags = flags || '';

src/addons/matchrecursive.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default (XRegExp) => {
2929
* @param {String} str String to search.
3030
* @param {String} left Left delimiter as an XRegExp pattern.
3131
* @param {String} right Right delimiter as an XRegExp pattern.
32-
* @param {String} [flags] Any native or XRegExp flags, used for the left and right delimiters.
32+
* @param {String} [flags] Any combination of XRegExp flags, used for the left and right delimiters.
3333
* @param {Object} [options] Lets you specify `valueNames` and `escapeChar` options.
3434
* @returns {!Array} Array of matches, or an empty array.
3535
* @example

src/xregexp.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,8 @@ XRegExp.addToken = (regex, handler, options) => {
752752
* @returns {RegExp} Cached XRegExp object.
753753
* @example
754754
*
755-
* while (match = XRegExp.cache('.', 'gs').exec(str)) {
755+
* let match;
756+
* while (match = XRegExp.cache('.', 'gs').exec('abc')) {
756757
* // The regex is compiled once only
757758
* }
758759
*/
@@ -778,15 +779,15 @@ XRegExp.cache.flush = (cacheName) => {
778779

779780
/**
780781
* Escapes any regular expression metacharacters, for use when matching literal strings. The result
781-
* can safely be used at any point within a regex that uses any flags.
782+
* can safely be used at any position within a regex that uses any flags.
782783
*
783784
* @memberOf XRegExp
784785
* @param {String} str String to escape.
785786
* @returns {string} String with regex metacharacters escaped.
786787
* @example
787788
*
788789
* XRegExp.escape('Escaped? <.>');
789-
* // -> 'Escaped\?\ <\.>'
790+
* // -> 'Escaped\?\u0020<\.>'
790791
*/
791792
XRegExp.escape = (str) => String(nullThrows(str)).replace(/[-\[\]{}()*+?.,\\^$|#\s]/g, (match) => {
792793
if (/\s/.test(match)) {
@@ -1071,8 +1072,8 @@ XRegExp.match = (str, regex, scope) => {
10711072
* // -> ['2', '4', '56']
10721073
*
10731074
* // Passing forward and returning specific backreferences
1074-
* html = '<a href="http://xregexp.com/api/">XRegExp</a>\
1075-
* <a href="http://www.google.com/">Google</a>';
1075+
* const html = `<a href="http://xregexp.com/api/">XRegExp</a>
1076+
* <a href="http://www.google.com/">Google</a>`;
10761077
* XRegExp.matchChain(html, [
10771078
* {regex: /<a href="([^"]+)">/i, backref: 1},
10781079
* {regex: XRegExp('(?i)^https?://(?<domain>[^/?#]+)'), backref: 'domain'}
@@ -1120,7 +1121,7 @@ XRegExp.matchChain = (str, chain) => (function recurseChain(values, level) {
11201121
* Returns a new string with one or all matches of a pattern replaced. The pattern can be a string
11211122
* or regex, and the replacement can be a string or a function to be called for each match. To
11221123
* perform a global search and replace, use the optional `scope` argument or include flag g if using
1123-
* a regex. Replacement strings can use `${n}` or `$<n>` for named and numbered backreferences.
1124+
* a regex. Replacement strings can use `$<n>` or `${n}` for named and numbered backreferences.
11241125
* Replacement functions can use named backreferences via the last argument. Also fixes browser bugs
11251126
* compared to the native `String.prototype.replace` and can be used reliably cross-browser.
11261127
*
@@ -1138,7 +1139,7 @@ XRegExp.matchChain = (str, chain) => (function recurseChain(values, level) {
11381139
* - $<n>, ${n} - Where n is a name or any number of digits that reference an existing capturing
11391140
* group, inserts backreference n.
11401141
* Replacement functions are invoked with three or more arguments:
1141-
* - args[0] - The matched substring (corresponds to `$&`` above). If the `namespacing` feature
1142+
* - args[0] - The matched substring (corresponds to `$&` above). If the `namespacing` feature
11421143
* is off, named backreferences are accessible as properties of this argument.
11431144
* - args[1..n] - One argument for each backreference (corresponding to `$1`, `$2`, etc. above).
11441145
* If the regex has no capturing groups, no arguments appear in this position.
@@ -1206,8 +1207,8 @@ XRegExp.replace = (str, search, replacement, scope) => {
12061207
* array of replacement details. Later replacements operate on the output of earlier replacements.
12071208
* Replacement details are accepted as an array with a regex or string to search for, the
12081209
* replacement string or function, and an optional scope of 'one' or 'all'. Uses the XRegExp
1209-
* replacement text syntax, which supports named backreference properties via `${name}` or
1210-
* `$<name>`.
1210+
* replacement text syntax, which supports named backreference properties via `$<name>` or
1211+
* `${name}`.
12111212
*
12121213
* @memberOf XRegExp
12131214
* @param {String} str String to search.
@@ -1216,12 +1217,12 @@ XRegExp.replace = (str, search, replacement, scope) => {
12161217
* @example
12171218
*
12181219
* str = XRegExp.replaceEach(str, [
1219-
* [XRegExp('(?<name>a)'), 'z${name}'],
1220+
* [XRegExp('(?<name>a)'), 'z$<name>'],
12201221
* [/b/gi, 'y'],
12211222
* [/c/g, 'x', 'one'], // scope 'one' overrides /g
12221223
* [/d/, 'w', 'all'], // scope 'all' overrides lack of /g
12231224
* ['e', 'v', 'all'], // scope 'all' allows replace-all for strings
1224-
* [/f/g, ($0) => $0.toUpperCase()]
1225+
* [/f/g, (match) => match.toUpperCase()]
12251226
* ]);
12261227
*/
12271228
XRegExp.replaceEach = (str, replacements) => {
@@ -1287,16 +1288,16 @@ XRegExp.split = (str, separator, limit) => fixed.split.call(nullThrows(str), sep
12871288
XRegExp.test = (str, regex, pos, sticky) => !!XRegExp.exec(str, regex, pos, sticky);
12881289

12891290
/**
1290-
* Uninstalls optional features according to the specified options. All optional features start out
1291-
* uninstalled, so this is used to undo the actions of `XRegExp.install`.
1291+
* Uninstalls optional features according to the specified options. Used to undo the actions of
1292+
* `XRegExp.install`.
12921293
*
12931294
* @memberOf XRegExp
12941295
* @param {Object|String} options Options object or string.
12951296
* @example
12961297
*
12971298
* // With an options object
12981299
* XRegExp.uninstall({
1299-
* // Disables support for astral code points in Unicode addons
1300+
* // Disables support for astral code points in Unicode addons (unless enabled per regex)
13001301
* astral: true,
13011302
*
13021303
* // Don't add named capture groups to the `groups` property of matches

types/index.d.ts

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ declare namespace XRegExp {
534534
* minutes: /^[0-5][0-9]$/
535535
* });
536536
* time.test('10:59'); // -> true
537-
* XRegExp.exec('10:59', time).minutes; // -> '59'
537+
* XRegExp.exec('10:59', time).groups.minutes; // -> '59'
538538
*/
539539
function build(pattern: string, subs: Record<string, Pattern>, flags?: string): RegExp;
540540

@@ -547,22 +547,23 @@ declare namespace XRegExp {
547547
* @returns Cached XRegExp object.
548548
* @example
549549
*
550-
* while (match = XRegExp.cache('.', 'gs').exec(str)) {
550+
* let match;
551+
* while (match = XRegExp.cache('.', 'gs').exec('abc')) {
551552
* // The regex is compiled once only
552553
* }
553554
*/
554555
function cache(pattern: string, flags: string): RegExp;
555556

556557
/**
557558
* Escapes any regular expression metacharacters, for use when matching literal strings. The result
558-
* can safely be used at any point within a regex that uses any flags.
559+
* can safely be used at any position within a regex that uses any flags.
559560
*
560561
* @param str - String to escape.
561562
* @returns String with regex metacharacters escaped.
562563
* @example
563564
*
564565
* XRegExp.escape('Escaped? <.>');
565-
* // -> 'Escaped\?\ <\.>'
566+
* // -> 'Escaped\?\u0020<\.>'
566567
*/
567568
function escape(str: string): string;
568569

@@ -732,8 +733,8 @@ declare namespace XRegExp {
732733
* // -> ['2', '4', '56']
733734
*
734735
* // Passing forward and returning specific backreferences
735-
* html = '<a href="http://xregexp.com/api/">XRegExp</a>\
736-
* <a href="http://www.google.com/">Google</a>';
736+
* const html = `<a href="http://xregexp.com/api/">XRegExp</a>
737+
* <a href="http://www.google.com/">Google</a>`;
737738
* XRegExp.matchChain(html, [
738739
* {regex: /<a href="([^"]+)">/i, backref: 1},
739740
* {regex: XRegExp('(?i)^https?://(?<domain>[^/?#]+)'), backref: 'domain'}
@@ -750,7 +751,7 @@ declare namespace XRegExp {
750751
* @param str - String to search.
751752
* @param left - Left delimiter as an XRegExp pattern.
752753
* @param right - Right delimiter as an XRegExp pattern.
753-
* @param flags - Any native or XRegExp flags, used for the left and right delimiters.
754+
* @param flags - Any combination of XRegExp flags, used for the left and right delimiters.
754755
* @param options - Lets you specify `valueNames` and `escapeChar` options.
755756
* @returns Array of matches, or an empty array.
756757
* @example
@@ -799,7 +800,7 @@ declare namespace XRegExp {
799800
* Returns a new string with one or all matches of a pattern replaced. The pattern can be a string
800801
* or regex, and the replacement can be a string or a function to be called for each match. To
801802
* perform a global search and replace, use the optional `scope` argument or include flag g if using
802-
* a regex. Replacement strings can use `${n}` or `$<n>` for named and numbered backreferences.
803+
* a regex. Replacement strings can use `$<n>` or `${n}` for named and numbered backreferences.
803804
* Replacement functions can use named backreferences via the last argument. Also fixes browser bugs
804805
* compared to the native `String.prototype.replace` and can be used reliably cross-browser.
805806
*
@@ -834,21 +835,21 @@ declare namespace XRegExp {
834835
* array of replacement details. Later replacements operate on the output of earlier replacements.
835836
* Replacement details are accepted as an array with a regex or string to search for, the
836837
* replacement string or function, and an optional scope of 'one' or 'all'. Uses the XRegExp
837-
* replacement text syntax, which supports named backreference properties via `${name}` or
838-
* `$<name>`.
838+
* replacement text syntax, which supports named backreference properties via `$<name>` or
839+
* `${name}`.
839840
*
840841
* @param str - String to search.
841842
* @param replacements - Array of replacement detail arrays.
842843
* @returns New string with all replacements.
843844
* @example
844845
*
845846
* str = XRegExp.replaceEach(str, [
846-
* [XRegExp('(?<name>a)'), 'z${name}'],
847+
* [XRegExp('(?<name>a)'), 'z$<name>'],
847848
* [/b/gi, 'y'],
848849
* [/c/g, 'x', 'one'], // scope 'one' overrides /g
849850
* [/d/, 'w', 'all'], // scope 'all' overrides lack of /g
850851
* ['e', 'v', 'all'], // scope 'all' allows replace-all for strings
851-
* [/f/g, ($0) => $0.toUpperCase()]
852+
* [/f/g, (match) => match.toUpperCase()]
852853
* ]);
853854
*/
854855
function replaceEach(str: string, replacements: ReplacementDetail[]): string;
@@ -894,14 +895,17 @@ declare namespace XRegExp {
894895
* @returns Handler for template literals that construct regexes with XRegExp syntax.
895896
* @example
896897
*
897-
* const h12 = /1[0-2]|0?[1-9]/;
898-
* const h24 = /2[0-3]|[01][0-9]/;
899-
* const hours = XRegExp.tag('x')`${h12} : | ${h24}`;
900-
* const minutes = /^[0-5][0-9]$/;
901-
* // Note that explicitly naming the 'minutes' group is required for named backreferences
902-
* const time = XRegExp.tag('x')`^ ${hours} (?<minutes>${minutes}) $`;
898+
* XRegExp.tag()`\b\w+\b`.test('word'); // -> true
899+
*
900+
* const hours = /1[0-2]|0?[1-9]/;
901+
* const minutes = /(?<minutes>[0-5][0-9])/;
902+
* const time = XRegExp.tag('x')`\b ${hours} : ${minutes} \b`;
903903
* time.test('10:59'); // -> true
904-
* XRegExp.exec('10:59', time).minutes; // -> '59'
904+
* XRegExp.exec('10:59', time).groups.minutes; // -> '59'
905+
*
906+
* const backref1 = /(a)\1/;
907+
* const backref2 = /(b)\1/;
908+
* XRegExp.tag()`${backref1}${backref2}`.test('aabb'); // -> true
905909
*/
906910
function tag(flags?: string | null): (literals: TemplateStringsArray, ...substitutions: any[]) => RegExp;
907911

@@ -930,15 +934,15 @@ declare namespace XRegExp {
930934
function test(str: string, regex: Pattern, pos?: number, sticky?: boolean | 'sticky'): boolean;
931935

932936
/**
933-
* Uninstalls optional features according to the specified options. All optional features start out
934-
* uninstalled, so this is used to undo the actions of `XRegExp.install`.
937+
* Uninstalls optional features according to the specified options. Used to undo the actions of
938+
* `XRegExp.install`.
935939
*
936940
* @param options - Options object or string.
937941
* @example
938942
*
939943
* // With an options object
940944
* XRegExp.uninstall({
941-
* // Disables support for astral code points in Unicode addons
945+
* // Disables support for astral code points in Unicode addons (unless enabled per regex)
942946
* astral: true,
943947
*
944948
* // Don't add named capture groups to the `groups` property of matches

0 commit comments

Comments
 (0)