diff --git a/README.md b/README.md index 0d5f8ad..35580cc 100644 --- a/README.md +++ b/README.md @@ -13,17 +13,20 @@ This library allows users to create regular expressions in a structured way, mak const hexColor = /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/; // After -const hexDigit = charClass(charRange('a', 'f'), charRange('A', 'F'), charRange('0', '9')); +const hexDigit = charClass( + charRange('a', 'f'), // + charRange('A', 'F'), + charRange('0', '9'), +); -// prettier-ignore const hexColor = buildRegex( startOfString, optionally('#'), capture( choiceOf( - repeat({ count: 6 }, hexDigit), - repeat({ count: 3 }, hexDigit), - ) + repeat({ count: 6 }, hexDigit), // #rrggbb + repeat({ count: 3 }, hexDigit), // #rgb + ), ), endOfString, ); @@ -73,11 +76,11 @@ const currencyAmount = buildRegex([ choiceOf( '$', '€', - repeat({ count: 3 }, charRange('A', 'Z')) // ISO currency code + repeat({ count: 3 }, charRange('A', 'Z')), // ISO currency code ), capture( oneOrMore(digit), // Integer part - optionally(['.', repeat({ count: 2 }, digit)]) // Fractional part + optionally(['.', repeat({ count: 2 }, digit)]), // Fractional part ), ]); ``` diff --git a/package.json b/package.json index 498c7fd..9bf19ea 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,7 @@ "quoteProps": "consistent", "singleQuote": true, "tabWidth": 2, - "trailingComma": "es5", + "trailingComma": "all", "useTabs": false }, "react-native-builder-bob": { diff --git a/src/components/__tests__/character-class.test.ts b/src/components/__tests__/character-class.test.ts index eaab83f..8673b3b 100644 --- a/src/components/__tests__/character-class.test.ts +++ b/src/components/__tests__/character-class.test.ts @@ -88,6 +88,12 @@ test('`anyOf` moves hyphen to the last position', () => { expect(anyOf('a-bc')).toHavePattern(/[abc-]/); }); +test('`anyOf` edge case caret and hyphen', () => { + expect(anyOf('^-')).toHavePattern(/[\^-]/); + expect(anyOf('-^')).toHavePattern(/[\^-]/); + expect(anyOf('-^a')).toHavePattern(/[a^-]/); +}); + test('`anyOf` throws on empty text', () => { expect(() => anyOf('')).toThrowErrorMatchingInlineSnapshot( `"\`anyOf\` should received at least one character"` diff --git a/src/components/character-class.ts b/src/components/character-class.ts index 4279779..9d8af29 100644 --- a/src/components/character-class.ts +++ b/src/components/character-class.ts @@ -129,13 +129,17 @@ function encodeCharacterClass(this: CharacterClass): EncodeOutput { // first (or last) place in order to treat it as hyphen character and not a range. // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Character_classes#types const hyphen = this.chars.includes('-') ? '-' : ''; - const otherChars = this.chars.filter((c) => c !== '-').join(''); + const caret = this.chars.includes('^') ? '^' : ''; + const otherChars = this.chars.filter((c) => c !== '-' && c !== '^').join(''); const ranges = this.ranges.map(({ start, end }) => `${start}-${end}`).join(''); const isInverted = this.isInverted ? '^' : ''; + let pattern = `[${isInverted}${ranges}${otherChars}${caret}${hyphen}]`; + if (pattern === '[^-]') pattern = '[\\^-]'; + return { precedence: 'atom', - pattern: `[${isInverted}${ranges}${otherChars}${hyphen}]`, + pattern, }; }