Skip to content

Commit

Permalink
Fix \P unicode escape in unicodeSets + ignoreCase mode (#101)
Browse files Browse the repository at this point in the history
* refactor: extract regenerate-plugin-tocode

* fix \P unicode escape in unicode sets mode

* add isIgnoreCaseMode
  • Loading branch information
JLHwung authored Oct 15, 2024
1 parent 60a4444 commit 5cfd6b9
Show file tree
Hide file tree
Showing 11 changed files with 244 additions and 46 deletions.
101 changes: 101 additions & 0 deletions data/all-characters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Generated using `npm run build`. Do not edit.
'use strict';

const regenerate = require('regenerate');

exports.UNICODE_SET = regenerate()
.addRange(0x0, 0x10FFFF)

exports.UNICODE_IV_SET = regenerate(0xD7, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x133, 0x135, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x180, 0x183, 0x185, 0x188, 0x192, 0x195, 0x19E, 0x1A1, 0x1A3, 0x1A5, 0x1A8, 0x1AD, 0x1B0, 0x1B4, 0x1B6, 0x1C6, 0x1C9, 0x1CC, 0x1CE, 0x1D0, 0x1D2, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0x1DF, 0x1E1, 0x1E3, 0x1E5, 0x1E7, 0x1E9, 0x1EB, 0x1ED, 0x1F3, 0x1F5, 0x1F9, 0x1FB, 0x1FD, 0x1FF, 0x201, 0x203, 0x205, 0x207, 0x209, 0x20B, 0x20D, 0x20F, 0x211, 0x213, 0x215, 0x217, 0x219, 0x21B, 0x21D, 0x21F, 0x221, 0x223, 0x225, 0x227, 0x229, 0x22B, 0x22D, 0x22F, 0x231, 0x23C, 0x242, 0x247, 0x249, 0x24B, 0x24D, 0x371, 0x387, 0x38B, 0x38D, 0x390, 0x3A2, 0x3D7, 0x3D9, 0x3DB, 0x3DD, 0x3DF, 0x3E1, 0x3E3, 0x3E5, 0x3E7, 0x3E9, 0x3EB, 0x3ED, 0x3EF, 0x3F6, 0x3F8, 0x461, 0x463, 0x465, 0x467, 0x469, 0x46B, 0x46D, 0x46F, 0x471, 0x473, 0x475, 0x477, 0x479, 0x47B, 0x47D, 0x47F, 0x48B, 0x48D, 0x48F, 0x491, 0x493, 0x495, 0x497, 0x499, 0x49B, 0x49D, 0x49F, 0x4A1, 0x4A3, 0x4A5, 0x4A7, 0x4A9, 0x4AB, 0x4AD, 0x4AF, 0x4B1, 0x4B3, 0x4B5, 0x4B7, 0x4B9, 0x4BB, 0x4BD, 0x4BF, 0x4C2, 0x4C4, 0x4C6, 0x4C8, 0x4CA, 0x4CC, 0x4D1, 0x4D3, 0x4D5, 0x4D7, 0x4D9, 0x4DB, 0x4DD, 0x4DF, 0x4E1, 0x4E3, 0x4E5, 0x4E7, 0x4E9, 0x4EB, 0x4ED, 0x4EF, 0x4F1, 0x4F3, 0x4F5, 0x4F7, 0x4F9, 0x4FB, 0x4FD, 0x4FF, 0x501, 0x503, 0x505, 0x507, 0x509, 0x50B, 0x50D, 0x50F, 0x511, 0x513, 0x515, 0x517, 0x519, 0x51B, 0x51D, 0x51F, 0x521, 0x523, 0x525, 0x527, 0x529, 0x52B, 0x52D, 0x10C6, 0x1E01, 0x1E03, 0x1E05, 0x1E07, 0x1E09, 0x1E0B, 0x1E0D, 0x1E0F, 0x1E11, 0x1E13, 0x1E15, 0x1E17, 0x1E19, 0x1E1B, 0x1E1D, 0x1E1F, 0x1E21, 0x1E23, 0x1E25, 0x1E27, 0x1E29, 0x1E2B, 0x1E2D, 0x1E2F, 0x1E31, 0x1E33, 0x1E35, 0x1E37, 0x1E39, 0x1E3B, 0x1E3D, 0x1E3F, 0x1E41, 0x1E43, 0x1E45, 0x1E47, 0x1E49, 0x1E4B, 0x1E4D, 0x1E4F, 0x1E51, 0x1E53, 0x1E55, 0x1E57, 0x1E59, 0x1E5B, 0x1E5D, 0x1E5F, 0x1E61, 0x1E63, 0x1E65, 0x1E67, 0x1E69, 0x1E6B, 0x1E6D, 0x1E6F, 0x1E71, 0x1E73, 0x1E75, 0x1E77, 0x1E79, 0x1E7B, 0x1E7D, 0x1E7F, 0x1E81, 0x1E83, 0x1E85, 0x1E87, 0x1E89, 0x1E8B, 0x1E8D, 0x1E8F, 0x1E91, 0x1E93, 0x1E9F, 0x1EA1, 0x1EA3, 0x1EA5, 0x1EA7, 0x1EA9, 0x1EAB, 0x1EAD, 0x1EAF, 0x1EB1, 0x1EB3, 0x1EB5, 0x1EB7, 0x1EB9, 0x1EBB, 0x1EBD, 0x1EBF, 0x1EC1, 0x1EC3, 0x1EC5, 0x1EC7, 0x1EC9, 0x1ECB, 0x1ECD, 0x1ECF, 0x1ED1, 0x1ED3, 0x1ED5, 0x1ED7, 0x1ED9, 0x1EDB, 0x1EDD, 0x1EDF, 0x1EE1, 0x1EE3, 0x1EE5, 0x1EE7, 0x1EE9, 0x1EEB, 0x1EED, 0x1EEF, 0x1EF1, 0x1EF3, 0x1EF5, 0x1EF7, 0x1EF9, 0x1EFB, 0x1EFD, 0x1F5A, 0x1F5C, 0x1F5E, 0x1FBD, 0x2C61, 0x2C68, 0x2C6A, 0x2C6C, 0x2C71, 0x2C81, 0x2C83, 0x2C85, 0x2C87, 0x2C89, 0x2C8B, 0x2C8D, 0x2C8F, 0x2C91, 0x2C93, 0x2C95, 0x2C97, 0x2C99, 0x2C9B, 0x2C9D, 0x2C9F, 0x2CA1, 0x2CA3, 0x2CA5, 0x2CA7, 0x2CA9, 0x2CAB, 0x2CAD, 0x2CAF, 0x2CB1, 0x2CB3, 0x2CB5, 0x2CB7, 0x2CB9, 0x2CBB, 0x2CBD, 0x2CBF, 0x2CC1, 0x2CC3, 0x2CC5, 0x2CC7, 0x2CC9, 0x2CCB, 0x2CCD, 0x2CCF, 0x2CD1, 0x2CD3, 0x2CD5, 0x2CD7, 0x2CD9, 0x2CDB, 0x2CDD, 0x2CDF, 0x2CE1, 0x2CEC, 0xA641, 0xA643, 0xA645, 0xA647, 0xA649, 0xA64B, 0xA64D, 0xA64F, 0xA651, 0xA653, 0xA655, 0xA657, 0xA659, 0xA65B, 0xA65D, 0xA65F, 0xA661, 0xA663, 0xA665, 0xA667, 0xA669, 0xA66B, 0xA681, 0xA683, 0xA685, 0xA687, 0xA689, 0xA68B, 0xA68D, 0xA68F, 0xA691, 0xA693, 0xA695, 0xA697, 0xA699, 0xA723, 0xA725, 0xA727, 0xA729, 0xA72B, 0xA72D, 0xA733, 0xA735, 0xA737, 0xA739, 0xA73B, 0xA73D, 0xA73F, 0xA741, 0xA743, 0xA745, 0xA747, 0xA749, 0xA74B, 0xA74D, 0xA74F, 0xA751, 0xA753, 0xA755, 0xA757, 0xA759, 0xA75B, 0xA75D, 0xA75F, 0xA761, 0xA763, 0xA765, 0xA767, 0xA769, 0xA76B, 0xA76D, 0xA77A, 0xA77C, 0xA77F, 0xA781, 0xA783, 0xA785, 0xA78C, 0xA791, 0xA797, 0xA799, 0xA79B, 0xA79D, 0xA79F, 0xA7A1, 0xA7A3, 0xA7A5, 0xA7A7, 0xA7A9, 0xA7AF, 0xA7B5, 0xA7B7, 0xA7B9, 0xA7BB, 0xA7BD, 0xA7BF, 0xA7C1, 0xA7C3, 0xA7C8, 0xA7CA, 0xA7D7, 0xA7D9, 0xA7DB, 0x1057B, 0x1058B, 0x10593)
.addRange(0x0, 0x40)
.addRange(0x5B, 0xB4)
.addRange(0xB6, 0xBF)
.addRange(0xDF, 0xFF)
.addRange(0x12F, 0x131)
.addRange(0x137, 0x138)
.addRange(0x148, 0x149)
.addRange(0x18C, 0x18D)
.addRange(0x199, 0x19B)
.addRange(0x1AA, 0x1AB)
.addRange(0x1B9, 0x1BB)
.addRange(0x1BD, 0x1C3)
.addRange(0x1DC, 0x1DD)
.addRange(0x1EF, 0x1F0)
.addRange(0x233, 0x239)
.addRange(0x23F, 0x240)
.addRange(0x24F, 0x344)
.addRange(0x346, 0x36F)
.addRange(0x373, 0x375)
.addRange(0x377, 0x37E)
.addRange(0x380, 0x385)
.addRange(0x3AC, 0x3C1)
.addRange(0x3C3, 0x3CE)
.addRange(0x3D2, 0x3D4)
.addRange(0x3F2, 0x3F3)
.addRange(0x3FB, 0x3FC)
.addRange(0x430, 0x45F)
.addRange(0x481, 0x489)
.addRange(0x4CE, 0x4CF)
.addRange(0x52F, 0x530)
.addRange(0x557, 0x109F)
.addRange(0x10C8, 0x10CC)
.addRange(0x10CE, 0x13F7)
.addRange(0x13FE, 0x1C7F)
.addRange(0x1C8A, 0x1C8F)
.addRange(0x1CBB, 0x1CBC)
.addRange(0x1CC0, 0x1DFF)
.addRange(0x1E95, 0x1E9A)
.addRange(0x1E9C, 0x1E9D)
.addRange(0x1EFF, 0x1F07)
.addRange(0x1F10, 0x1F17)
.addRange(0x1F1E, 0x1F27)
.addRange(0x1F30, 0x1F37)
.addRange(0x1F40, 0x1F47)
.addRange(0x1F4E, 0x1F58)
.addRange(0x1F60, 0x1F67)
.addRange(0x1F70, 0x1F87)
.addRange(0x1F90, 0x1F97)
.addRange(0x1FA0, 0x1FA7)
.addRange(0x1FB0, 0x1FB7)
.addRange(0x1FBF, 0x1FC7)
.addRange(0x1FCD, 0x1FD2)
.addRange(0x1FD4, 0x1FD7)
.addRange(0x1FDC, 0x1FE2)
.addRange(0x1FE4, 0x1FE7)
.addRange(0x1FED, 0x1FF7)
.addRange(0x1FFD, 0x2125)
.addRange(0x2127, 0x2129)
.addRange(0x212C, 0x2131)
.addRange(0x2133, 0x215F)
.addRange(0x2170, 0x2182)
.addRange(0x2184, 0x24B5)
.addRange(0x24D0, 0x2BFF)
.addRange(0x2C30, 0x2C5F)
.addRange(0x2C65, 0x2C66)
.addRange(0x2C73, 0x2C74)
.addRange(0x2C76, 0x2C7D)
.addRange(0x2CE3, 0x2CEA)
.addRange(0x2CEE, 0x2CF1)
.addRange(0x2CF3, 0xA63F)
.addRange(0xA66D, 0xA67F)
.addRange(0xA69B, 0xA721)
.addRange(0xA72F, 0xA731)
.addRange(0xA76F, 0xA778)
.addRange(0xA787, 0xA78A)
.addRange(0xA78E, 0xA78F)
.addRange(0xA793, 0xA795)
.addRange(0xA7CD, 0xA7CF)
.addRange(0xA7D1, 0xA7D5)
.addRange(0xA7DD, 0xA7F4)
.addRange(0xA7F6, 0xAB6F)
.addRange(0xABC0, 0xFB04)
.addRange(0xFB06, 0xFF20)
.addRange(0xFF3B, 0x103FF)
.addRange(0x10428, 0x104AF)
.addRange(0x104D4, 0x1056F)
.addRange(0x10596, 0x10C7F)
.addRange(0x10CB3, 0x10D4F)
.addRange(0x10D66, 0x1189F)
.addRange(0x118C0, 0x16E3F)
.addRange(0x16E60, 0x1E8FF)
.addRange(0x1E922, 0x10FFFF)
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@
"files": [
"LICENSE-MIT.txt",
"rewrite-pattern.js",
"data/all-characters.js",
"data/character-class-escape-sets.js",
"data/i-bmp-mappings.js",
"data/iu-mappings.js"
],
"scripts": {
"build": "node scripts/case-mappings.js && node scripts/character-class-escape-sets.js",
"build": "node scripts/index.js",
"test": "node --test tests/tests.js",
"test-node6": "mocha tests",
"cover": "NODE_V8_COVERAGE=coverage node --test --experimental-test-coverage tests/tests.js"
Expand Down
26 changes: 15 additions & 11 deletions rewrite-pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const unicodeMatchPropertyValue = require('unicode-match-property-value-ecmascri
const iuMappings = require('./data/iu-mappings.js');
const iBMPMappings = require('./data/i-bmp-mappings.js');
const ESCAPE_SETS = require('./data/character-class-escape-sets.js');
const { UNICODE_SET, UNICODE_IV_SET } = require('./data/all-characters.js');

function flatMap(array, callback) {
const result = [];
Expand All @@ -30,10 +31,6 @@ function regenerateContainsAstral(regenerateData) {
// https://tc39.es/ecma262/#prod-SyntaxCharacter
const SYNTAX_CHARS = /[\\^$.*+?()[\]{}|]/g;

// Prepare a Regenerate set containing all code points, used for negative
// character classes (if any).
const UNICODE_SET = regenerate().addRange(0x0, 0x10FFFF);

const ASTRAL_SET = regenerate().addRange(0x10000, 0x10FFFF);

const NEWLINE_SET = regenerate().add(
Expand Down Expand Up @@ -96,7 +93,7 @@ const handleLoneUnicodePropertyNameOrValue = (value) => {
return getUnicodePropertyValueSet(property);
};

const getUnicodePropertyEscapeSet = (value, isNegative) => {
const getUnicodePropertyEscapeSet = (value, isNegative, isUnicodeSetIgnoreCase) => {
const parts = value.split('=');
const firstPart = parts[0];
let set;
Expand All @@ -113,7 +110,7 @@ const getUnicodePropertyEscapeSet = (value, isNegative) => {
throw new Error('Cannot negate Unicode property of strings');
}
return {
characters: UNICODE_SET.clone().remove(set.characters),
characters: (isUnicodeSetIgnoreCase ? UNICODE_IV_SET : UNICODE_SET).clone().remove(set.characters),
strings: new Set()
};
}
Expand All @@ -126,8 +123,8 @@ const getUnicodePropertyEscapeSet = (value, isNegative) => {
};
};

const getUnicodePropertyEscapeCharacterClassData = (property, isNegative) => {
const set = getUnicodePropertyEscapeSet(property, isNegative);
const getUnicodePropertyEscapeCharacterClassData = (property, isNegative, isUnicodeSetIgnoreCase) => {
const set = getUnicodePropertyEscapeSet(property, isNegative, isUnicodeSetIgnoreCase);
const data = getCharacterClassEmptyData();
const singleChars = set.characters;
const caseFoldFlags = configGetCaseFoldFlags();
Expand Down Expand Up @@ -477,12 +474,16 @@ const computeCharacterClass = (characterClassItem, regenerateOptions) => {
));
break;
case 'unicodePropertyEscape':
const nestedData = getUnicodePropertyEscapeCharacterClassData(item.value, item.negative);
const nestedData = getUnicodePropertyEscapeCharacterClassData(
item.value,
item.negative,
config.flags.unicodeSets && config.isIgnoreCaseMode
);
handlePositive.nested(data, nestedData);
data.transformed =
data.transformed ||
config.transform.unicodePropertyEscapes ||
(config.transform.unicodeSetsFlag && (nestedData.maybeIncludesStrings || characterClassItem.kind !== "union"));
(config.transform.unicodeSetsFlag && (nestedData.maybeIncludesStrings || characterClassItem.kind !== "union" || item.negative));
break;
case 'characterClass':
const handler = item.negative ? handleNegative : handlePositive;
Expand Down Expand Up @@ -621,7 +622,7 @@ const processTerm = (item, regenerateOptions, groups) => {
item = processCharacterClass(item, regenerateOptions);
break;
case 'unicodePropertyEscape':
const data = getUnicodePropertyEscapeCharacterClassData(item.value, item.negative);
const data = getUnicodePropertyEscapeCharacterClassData(item.value, item.negative, config.flags.unicodeSets && config.isIgnoreCaseMode);
if (data.maybeIncludesStrings) {
if (!config.flags.unicodeSets) {
throw new Error(
Expand Down Expand Up @@ -800,6 +801,9 @@ const config = {
},
get isDotAllMode() {
return (this.modifiersData.s !== undefined ? this.modifiersData.s : this.flags.dotAll);
},
get isIgnoreCaseMode() {
return (this.modifiersData.i !== undefined ? this.modifiersData.i : this.flags.ignoreCase);
}
};

Expand Down
31 changes: 31 additions & 0 deletions scripts/all-characters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const fs = require('node:fs');
const regenerate = require('regenerate');
require('./utils/regenerate-plugin-to-code.js');

const commonMappings = require('@unicode/unicode-16.0.0/Case_Folding/C/code-points.js');
const simpleMappings = require('@unicode/unicode-16.0.0/Case_Folding/S/code-points.js');

// https://tc39.es/ecma262/#sec-allcharacters
const UNICODE_SET = regenerate().addRange(0x0, 0x10FFFF);
const UNICODE_IV_SET = regenerate().addRange(0x0, 0x10FFFF);

for (const cp of commonMappings.keys()) {
UNICODE_IV_SET.remove(cp);
}
for (const cp of simpleMappings.keys()) {
UNICODE_IV_SET.remove(cp);
}

const stringify = (name, set) => {
const source = 'exports.' + name + ' = ' + set.toCode();
return source;
};

const source = [
'// Generated using `npm run build`. Do not edit.\n' +
`'use strict';\n\nconst regenerate = require('regenerate');`,
stringify('UNICODE_SET', UNICODE_SET),
stringify('UNICODE_IV_SET', UNICODE_IV_SET)
].join('\n\n');

fs.writeFileSync('data/all-characters.js', source + '\n');
33 changes: 1 addition & 32 deletions scripts/character-class-escape-sets.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const fs = require('fs');
const jsesc = require('jsesc');
const regenerate = require('regenerate');
require('./utils/regenerate-plugin-to-code.js');

const Zs = require('@unicode/unicode-16.0.0/General_Category/Space_Separator/code-points.js');

Expand Down Expand Up @@ -83,38 +84,6 @@ addCharacterClassEscape(

/*----------------------------------------------------------------------------*/

const codePointToString = (codePoint) => {
return '0x' + codePoint.toString(16).toUpperCase();
};

// Regenerate plugin that turns a set into some JavaScript source code that
// generates that set.
regenerate.prototype.toCode = function() {
const data = this.data;
// Iterate over the data per `(start, end)` pair.
let index = 0;
let start;
let end;
const length = data.length;
const loneCodePoints = [];
const ranges = [];
while (index < length) {
start = data[index];
end = data[index + 1] - 1; // Note: the `- 1` makes `end` inclusive.
if (start == end) {
loneCodePoints.push(codePointToString(start));
} else {
ranges.push(
'addRange(' + codePointToString(start) +
', ' + codePointToString(end) + ')'
);
}
index += 2;
}
return 'regenerate(' + loneCodePoints.join(', ') + ')' +
(ranges.length ? '\n\t\t.' + ranges.join('\n\t\t.') : '');
};

const stringify = (name, object) => {
const source = 'exports.' + name + ' = new Map([\n\t' + Object.keys(object).map((character) => {
const set = object[character];
Expand Down
3 changes: 3 additions & 0 deletions scripts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require('./all-characters.js');
require('./case-mappings.js');
require('./character-class-escape-sets.js');
33 changes: 33 additions & 0 deletions scripts/utils/regenerate-plugin-to-code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const regenerate = require('regenerate');

const codePointToString = (codePoint) => {
return '0x' + codePoint.toString(16).toUpperCase();
};

// Regenerate plugin that turns a set into some JavaScript source code that
// generates that set.
regenerate.prototype.toCode = function regenerateToCode() {
const data = this.data;
// Iterate over the data per `(start, end)` pair.
let index = 0;
let start;
let end;
const length = data.length;
const loneCodePoints = [];
const ranges = [];
while (index < length) {
start = data[index];
end = data[index + 1] - 1; // Note: the `- 1` makes `end` inclusive.
if (start == end) {
loneCodePoints.push(codePointToString(start));
} else {
ranges.push(
'addRange(' + codePointToString(start) +
', ' + codePointToString(end) + ')'
);
}
index += 2;
}
return 'regenerate(' + loneCodePoints.join(', ') + ')' +
(ranges.length ? '\n\t\t.' + ranges.join('\n\t\t.') : '');
};
21 changes: 21 additions & 0 deletions tests/fixtures/modifiers.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,27 @@ const modifiersFixtures = [
'expected': '(?:[A-Za-z\\u017F\\u212A])a',
'expectedFlags': 'u'
},
{
'pattern': '(?i:[^\\P{Lowercase_Letter}])',
'flags': 'u',
'options': { unicodePropertyEscapes: 'transform', modifiers: 'transform' },
'matches': ['\u{0131}'],
'nonMatches': ['0', ',', 'k', 'K', '\u{212A}']
},
{
'pattern': '(?i:[^\\P{Lowercase_Letter}])',
'flags': 'v',
'options': { unicodeSetsFlag: 'transform', modifiers: 'transform' },
'matches': ['k', 'K', '\u{212A}', '\u{0131}'],
'nonMatches': ['0', ',']
},
{
'pattern': '(?i:[^\\P{Lowercase_Letter}])',
'flags': 'v',
'options': { unicodeSetsFlag: 'transform', unicodePropertyEscapes: 'transform', modifiers: 'transform' },
'matches': ['k', 'K', '\u{212A}', '\u{0131}'],
'nonMatches': ['0', ',']
},
// +m
{
'pattern': '(?m:^[a-z])',
Expand Down
14 changes: 14 additions & 0 deletions tests/fixtures/unicode-property-escape.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ const unicodePropertyEscapeFixtures = [
pattern: '(?:\\p{Script_Extensions=Wancho})',
expected: '(?:(?:\\uD838[\\uDEC0-\\uDEF9\\uDEFF]))',
},
{
pattern: '[\\p{ASCII}]',
flags: 'iu',
expected: '[\\0-\\x7F\\u017F\\u212A]',
expectedFlags: 'iu',
matches: ['k', 'K', '\u{212A}'],
nonMatches: ['\u{0131}']
},
{
pattern: '[^\\P{Lowercase_Letter}]',
flags: 'iu',
matches: ['\u{0131}'],
nonMatches: ['0', ',', 'k', 'K', '\u{212A}']
},
// simplifies the output using Unicode code point escapes when not transforming the u flag
{
pattern: '\\p{Script_Extensions=Anatolian_Hieroglyphs}',
Expand Down
21 changes: 21 additions & 0 deletions tests/fixtures/unicode-set.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,27 @@ const unicodeSetFixtures = [
matches: ['\n'],
options: { unicodeSetsFlag: 'transform', dotAllFlag: 'transform' },
expected: '[^]'
},
{
pattern: '[\\p{ASCII}]',
flags: 'iv',
expected: '[\\p{ASCII}]',
expectedFlags: 'iu',
matches: ['k', 'K', '\u{212A}'],
nonMatches: ['\u{0131}']
},
{
pattern: '[^\\P{ASCII}]',
flags: 'iv',
expectedFlags: 'iu',
matches: ['k', 'K', '\u{212A}'],
nonMatches: ['\u{0131}']
},
{
pattern: '[^\\P{Lowercase_Letter}]',
flags: 'iv',
matches: ['k', 'K', '\u{212A}', '\u{0131}'],
nonMatches: ['0', ',']
}
];

Expand Down
Loading

0 comments on commit 5cfd6b9

Please sign in to comment.