> For AI agents: the complete documentation index is available at https://rslint.rs/llms.txt, the full documentation bundle is available at https://rslint.rs/llms-full.txt.

# no-misleading-character-class

[Added in v0.5.0](https://github.com/web-infra-dev/rslint/releases/tag/v0.5.0)
## Configuration

| Preset                   | Configured Value |
| ------------------------ | ---------------- |
| ✅ js.configs.recommended | `"error"`        |


```ts title=rslint.config.ts
import { defineConfig, js } from '@rslint/core';

export default defineConfig([
  js.configs.recommended,
  {
    rules: {
      'no-misleading-character-class': 'error',
    },
  },
]);
```

## Rule Details

Disallow characters whose visual rendering is made from multiple code points
(combining marks, surrogate pairs, regional indicators, emoji-modifier
sequences, joined ZWJ sequences) from appearing inside a regex character class
`[...]`. Such sequences cannot be matched as a single unit by the regex engine
and therefore produce surprising matches.

Examples of **incorrect** code for this rule:

```javascript
/^[Á]$/u;        // a + combining acute
/^[❇️]$/u;       // base + variation selector
/^[👶🏻]$/u;     // base emoji + skin tone modifier
/^[🇯🇵]$/u;     // two regional indicator symbols
/^[👨‍👩‍👦]$/u; // ZWJ-joined family sequence
/^[👍]$/;        // astral character without `u` / `v` flag
new RegExp("[🎵]");
```

Examples of **correct** code for this rule:

```javascript
/^[abc]$/;
/^[👍]$/u;
/^[\q{👶🏻}]$/v; // v-flag grouping preserves the sequence
new RegExp("^[]$");
/[\ud83d\udc4d]/;
/[\u00B7\u0300-\u036F]/u;
```

### Options

This rule accepts an options object:

```json
{ "no-misleading-character-class": ["error", { "allowEscape": true }] }
```

- `allowEscape` (boolean, default `false`) — when enabled, allows combining
  the troublesome characters inside a character class as long as the
  combining portion is written using a backslash escape sequence. This
  applies to regex literals and to `RegExp(...)` calls whose first argument
  is a string or no-substitution template literal.

Examples of **correct** code with `{ "allowEscape": true }`:

```javascript
/[\ud83d\udc4d]/;                // surrogate pair written with escapes
/[A\u0301]/;                     // combining acute written with escape
new RegExp("[\\uD83D\\uDC4D]");  // surrogate pair in string literal
```

## Differences from ESLint

- The scope of recognition for the `RegExp(...)` constructor is limited to
  calls where the callee is a recognized global `RegExp` constructor and the
  pattern or flags are statically known strings. Spread arguments and
  unresolved runtime expressions are ignored.
- When a regex literal is passed to `RegExp(...)` with an unresolved second
  flags argument, rslint does not report on the literal because the runtime
  flags may override the literal's own flags.
- Suggestions to add the `u` flag use a simplified heuristic to decide
  whether the pattern remains valid under the flag. Patterns with identity
  escapes on letters (e.g. `/[👍]\a/`) are correctly detected as unfixable;
  more exotic cases may rarely produce a suggestion that ESLint would
  suppress.
- In rare edge cases where a character written as `\q{...}` or `\p{...}`
  escape appears outside its valid flag context (e.g. without the v flag),
  the scanner may still treat it as a breaker rather than a plain character.
- TypeScript-only code that repeatedly merges the same name across namespace,
  type-only, decorator, and parameter scopes can differ in whether an assigned
  `RegExp` alias is considered local. Ordinary lexical bindings and namespace
  shadowing are supported.

## Original Documentation

- [ESLint: no-misleading-character-class](https://eslint.org/docs/latest/rules/no-misleading-character-class)
- [Source code](https://github.com/eslint/eslint/blob/v10.8.1/lib/rules/no-misleading-character-class.js)
