Character class: [...], [^...]
==============================

A **character class** matches any character in or not in a custom set of characters. When the `v` flag is enabled, it can also be used to match finite-length strings.

Syntax
------


```regex
[]
[abc]
[A-Z]

[^]
[^abc]
[^A-Z]

// `v` mode only
[operand1&&operand2]
[operand1--operand2]
[\q{substring}]
```

### Parameters

`operand1`, `operand2`

Can be a single character, another square-bracket-enclosed character class, a character class escape, a Unicode character class escape, or a string using the `\q` syntax.

`substring`

A literal string.

Description
-----------

A character class specifies a list of characters between square brackets and matches any character in the list. The `v` flag drastically changes how character classes are parsed and interpreted. The following syntaxes are available in both `v` mode and non-`v` mode:

* A single character: matches the character itself.
* A range of characters: matches any character in the inclusive range. The range is specified by two characters separated by a dash (`-`). The first character must be smaller in character value than the second character. The *character value* is the Unicode code point of the character. Because Unicode code points are usually assigned to alphabets in order, `[a-z]` specifies all lowercase Latin characters, while `[α-ω]` specifies all lowercase Greek characters. In Unicode-unaware mode, regexes are interpreted as a sequence of BMP characters. Therefore, surrogate pairs in character classes represent two characters instead of one; see below for details.
* Escape sequences: `\b`, `\-`, character class escapes, Unicode character class escapes, and other character escapes.

These syntaxes can occur any number of times, and the character sets they represent are unioned. For example, `/[a-zA-Z0-9]/` matches any letter or digit.

The `^` prefix in a character class creates a *complement class*. For example, `[^abc]` matches any character except `a`, `b`, or `c`. The `^` character is a literal character when it appears in the middle of a character class — for example, `[a^b]` matches the characters `a`, `^`, and `b`.

The lexical grammar does a very rough parse of regex literals, so that it does not end the regex literal at a `/` character which appears within a character class. This means `/[/]/` is valid without needing to escape the `/`.

The boundaries of a character range must not specify more than one character, which happens if you use a character class escape. For example:


```js
/[\s-9]/u; // SyntaxError: Invalid regular expression: Invalid character class
```


In Unicode-unaware mode, character ranges where one boundary is a character class makes the `-` become a literal character. This is a deprecated syntax for web compatibility, and you should not rely on it.


```js
/[\s-9]/.test("-"); // true
```


In Unicode-unaware mode, regexes are interpreted as a sequence of BMP characters. Therefore, surrogate pairs in character classes represent two characters instead of one.


```js
/[😄]/.test("\ud83d"); // true
/[😄]/u.test("\ud83d"); // false

/[😄-😛]/.test("😑"); // SyntaxError: Invalid regular expression: /[😄-😛]/: Range out of order in character class
/[😄-😛]/u.test("😑"); // true
```


Even if the pattern ignores case, the case of the two ends of a range is significant in determining which characters belong to the range. For example, the pattern `/[E-F]/i` only matches `E`, `F`, `e`, and `f`, while the pattern `/[E-f]/i` matches all uppercase and lowercase ASCII letters (because it spans over `E–Z` and `a–f`), as well as `[`, `\`, `]`, `^`, `_`, and ```.

### Non-v-mode character class

Non-`v`-mode character classes interpret most character literally and have less restrictions about the characters they can contain. For example, `.` is the literal dot character, not the wildcard. The only characters that cannot appear literally are `\`, `]`, and `-`.

* In character classes, most escape sequences are supported, except `\b`, `\B`, and backreferences. `\b` indicates a backspace character instead of a word boundary, while the other two cause syntax errors. To use `\` literally, escape it as `\\`.
* The `]` character indicates the end of the character class. To use it literally, escape it as `\]`.
* The dash (`-`) character, when used between two characters, indicates a range. When it appears at the start or end of a character class, it is a literal character. It's also a literal character when it's used in the boundary of a range. For example, `[a-]` matches the characters `a` and `-`, `[!--]` matches the characters `!` to `-`, and `[--9]` matches the characters `-` to `9`. You can also escape it as `\-` if you want to use it literally anywhere.
### v-mode character class

The basic idea of character classes in `v` mode remains the same: you can still use most characters literally, use `-` to denote character ranges, and use escape sequences. One of the most important features of the `v` flag is *set notation* within character classes. As previously mentioned, normal character classes can express unions by concatenating two ranges, such as using `[A-Z0-9]` to mean "the union of the set `[A-Z]` and the set `[0-9]`". However, there's no easy way to represent other operations with character sets, such as intersection and difference.

With the `v` flag, intersection is expressed with `&&`, and subtraction with `--`. The absence of both implies union. The two operands of `&&` or `--` can be a character, character escape, character class escape, or even another character class. For example, to express "a word character that's not an underscore", you can use `[\w--_]`. You cannot mix operators on the same level. For example, `[\w&&[A-z]--_]` is a syntax error. However, because you can nest character classes, you can be explicit by writing `[\w&&[[A-z]--_]]` or `[[\w&&[A-z]]--_]` (which both mean `[A-Za-z]`). Similarly, `[AB--C]` is invalid and you need to write `[A[B--C]]` (which just means `[AB]`).

In `v` mode, the Unicode character class escape `\p` can match finite-length strings, such as emojis. For symmetry, regular character classes can also match more than one character. To write a "string literal" in a character class, you wrap the string in `\q{...}`. The only regex syntax supported here is disjunction — apart from this, `\q` must completely enclose literals (including escaped characters). This ensures that character classes can only match finite-length strings with finitely many possibilities.

Because the character class syntax is now more sophisticated, more characters are reserved and forbidden from appearing literally.

* In addition to `]` and `\`, the following characters must be escaped in character classes if they represent literal characters: `(`, `)`, `[`, `{`, `}`, `/`, `-`, `|`. This list is somewhat similar to the list of syntax characters, except that `^`, `$`, `*`, `+`, and `?` are not reserved inside character classes, while `/` and `-` are not reserved outside character classes (although `/` may delimit a regex literal and therefore still needs to be escaped). All these characters may also be optionally escaped in `u`-mode character classes.
* The following "double punctuator" sequences must be escaped as well (but they don't make much sense without the `v` flag anyway): `&&`, `!!`, `##`, `$$`, `%%`, `**`, `++`, `,,`, `..`, `::`, `;;`, `<<`, `==`, `>>`, `??`, `@@`, `^^`, ````, `~~`. In `u` mode, some of these characters can only appear literally within character classes and cause a syntax error when escaped. In `v` mode, they must be escaped when appearing in pairs, but can be optionally escaped when appearing alone. For example, `/[\!]/u` is invalid because it's an identity escape, but both `/[\!]/v` and `/[!]/v` are valid, while `/[!!]/v` is invalid. The literal character reference has a detailed table of which characters can appear escaped or unescaped.

Complement character classes `[^...]` cannot possibly be able to match strings longer than one character. For example, `[\q{ab|c}]` is valid and matches the string `"ab"`, but `[^\q{ab|c}]` is invalid because it's unclear how many characters should be consumed. The check is done by checking if all `\q` contain single characters and all `\p` specify character properties — for unions, all operands must be purely characters; for intersections, at least one operand must be purely characters; for subtraction, the leftmost operand must be purely characters. The check is syntactic without looking at the actual character set being specified, which means although `/[^\q{ab|c}--\q{ab}]/v` is equivalent to `/[^c]/v`, it's still rejected.

### Complement classes and case-insensitive matching

In non-`v`-mode, complement character classes `[^...]` are implemented by simply inverting the match result — that is, `[^...]` matches whenever `[...]` doesn't match, and vice versa. However, the other complement classes, such as `\P{...}` and `\W`, work by eagerly constructing the set consisting of all characters without the specified property. They seem to produce the same behavior, but are made more complex when combined with case-insensitive matching.

Consider the following two regexes:


```js
const r1 = /\p{Lowercase\_Letter}/iu;
const r2 = /[^\P{Lowercase\_Letter}]/iu;
```


The `r2` is a double negation and seems to be equivalent with `r1`. But in fact, `r1` matches all lower- and upper-case ASCII letters, while `r2` matches none. To illustrate how it works, pretend that we are only dealing with ASCII characters, not the entire Unicode character set, and `r1` and `r2` are specified as below:


```js
const r1 = /[a-z]/iu;
const r2 = /[^A-Z]/iu;
```


Recall that case-insensitive matching happens by folding both the pattern and the input to the same case (see `ignoreCase` for more details). For `r1`, the character class `a-z` stays the same after case folding, while both upper- and lower-case ASCII string inputs are folded to lower-case, so `r1` is able to match both `"A"` and `"a"`. For `r2`, the character class `A-Z` is folded to `a-z`; however, `^` negates the match result, so that `[^A-Z]` in effect only matches upper-case strings. However, both upper- and lower-case ASCII string inputs are still folded to lower-case, causing `r2` to match nothing.

In `v` mode, this behavior is fixed — `[^...]` also eagerly constructs the complement class instead of negating the match result. This makes `[^\P{Lowercase_Letter}]` and `\p{Lowercase_Letter}` are strictly equivalent.

Examples
--------

### Matching hexadecimal digits

The following function determines whether a string contains a valid hexadecimal number:


```js
function isHexadecimal(str) {
  return /^[0-9A-F]+$/i.test(str);
}

isHexadecimal("2F3"); // true
isHexadecimal("beef"); // true
isHexadecimal("undefined"); // false
```

### Using intersection

The following function matches Greek letters.


```js
function greekLetters(str) {
  return str.match(/[\p{Script\_Extensions=Greek}&&\p{Letter}]/gv);
}

// 𐆊 is U+1018A GREEK ZERO SIGN
greekLetters("π𐆊P0零αAΣ"); // [ 'π', 'α', 'Σ' ]
```

### Using subtraction

The following function matches all non-ASCII numbers.


```js
function nonASCIINumbers(str) {
  return str.match(/[\p{Decimal\_Number}--[0-9]]/gv);
}

// 𑜹 is U+11739 AHOM DIGIT NINE
nonASCIINumbers("𐆊0零1𝟜𑜹a"); // [ '𝟜', '𑜹' ]
```

### Matching strings

The following function matches all line terminator sequences, including the line terminator characters and the sequence `\r\n` (CRLF).


```js
function getLineTerminators(str) {
  return str.match(/[\r\n\u2028\u2029\q{\r\n}]/gv);
}

getLineTerminators(`
A poem\r
Is split\r\n
Into many
Stanzas
`); // [ '\r', '\r\n', '\n' ]
```


This example is exactly equivalent to `/(?:\r|\n|\u2028|\u2029|\r\n)/gu` or `/(?:[\r\n\u2028\u2029]|\r\n)/gu`, except shorter.

The most useful case of `\q{}` is when doing subtraction and intersection. Previously, this was possible with multiple lookaheads. The following function matches flags that are not one of the American, Chinese, Russian, British, and French flags.


```js
function notUNSCPermanentMember(flag) {
  return /^[\p{RGI\_Emoji\_Flag\_Sequence}--\q{🇺🇸|🇨🇳|🇷🇺|🇬🇧|🇫🇷}]$/v.test(flag);
}

notUNSCPermanentMember("🇺🇸"); // false
notUNSCPermanentMember("🇩🇪"); // true
```


This example is mostly equivalent to `/^(?!🇺🇸|🇨🇳|🇷🇺|🇬🇧|🇫🇷)\p{RGI_Emoji_Flag_Sequence}$/v`, except perhaps more performant.

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # prod-CharacterClass |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Character classes guide
* Regular expressions
* Character class escape: `\d`, `\D`, `\w`, `\W`, `\s`, `\S`
* Unicode character class escape: `\p{...}`, `\P{...}`
* Literal character: `a`, `b`
* Character escape: `\n`, `\u{...}`
* Disjunction: `|`
* RegExp v flag with set notation and properties of strings on v8.dev (2022)