Powrót do strony głównej

RegExp.escape() ekranuje litery i spacje: dlaczego

RegExp.escape() ekranuje litery łacińskie, cyfry i spacje dla bezpiecznej konkatenacji wyrażeń regularnych. Standard wymaga tego dla uniknięcia błędów z grupami przechwytywania i sekwencjami legacy. Zaleca się używanie z flagą u i polyfillem.

Dlaczego RegExp.escape() ukrywa litery w kodach \x?
Advertisement 728x90

# Ekranowanie w RegExp.escape(): dlaczego litery, cyfry i spacje stają się kodami \x

Funkcja RegExp.escape(), która pojawiła się w przeglądarkach w 2025 roku, ekranuje nie tylko znaki sterujące wyrażeń regularnych, ale także litery łacińskie, cyfry na początku ciągu, spacje i interpunkcję typu @. To odróżnia ją od tradycyjnych, samodzielnie napisanych funkcji escape, które ignorowały takie znaki. Standard ECMAScript wymaga tego w celu zapobiegania błędom podczas konkatenacji RegExp.

Przyczyny ekranowania cyfr i liter

Cyfry na początku ciągu są ekranowane, aby uniknąć ich interpretacji jako numerów grup przechwytywania lub kodów ósemkowych. Litery łacińskie — dla poprawnego działania z sekwencjami escape typu \c.

Przykład z cyfrą:

Google AdInline article slot
p = '2'
new RegExp('()\\1' + RegExp.escape(p)).source // ()\\1\\x32
new RegExp('()\\1' + p).source // ()\\12

Bez ekranowania \12 odnosi się do 12. grupy lub znaku o kodzie ósemkowym 12. Z ekranowaniem wyszukiwana jest grupa 1, po której następuje znak 2.

Przykład z literą:

p = 'a'
new RegExp('\\c' + RegExp.escape(p)).source // \\c\\x61
new RegExp('\\c' + p).source // \\ca

\ca jest interpretowane jako znak sterujący (kod 1), \c\x61 — jako sekwencja \c i a. W trybie Unicode (u lub v) takie konstrukcje powodują SyntaxError, co ułatwia debugowanie.

Google AdInline article slot

Spacje i interpunkcja: prewencyjna ochrona

Standard nie wyjaśnia ekranowania spacji i znaków typu @. W repozytorium TC39 wskazano: ekranowane są wszystkie znaki, które mogą spowodować "context escape" w przyszłości. To ustala wejście/wyjście z kontekstów tylko poprzez spacje lub interpunkcję ASCII.

Taki podejście jest kontrowersyjne: dodaje narzut bez bieżącej potrzeby. Propozycja flagi x do ignorowania spacji utknęła na pierwszej z czterech faz.

Porównanie z samodzielnymi funkcjami

Klasyczna funkcja escape z MDN (2020):

Google AdInline article slot
function escapeRegExp(string) {
    return string.replace(/[.*+?^${}()|[\\]\\]/g, '\\$&');
}

Pokrywa znaki sterujące, ale nie cyfry/litery. Ulepszona wersja z ekranowaniem początkowej cyfry i myślnika:

function escapeRegExp(string) {
    const coolCmd = string => string.replace(/[.*+?^${}()|[\\]\\]/g, '\\$&')
        .replaceAll('-', '\\x2d');
    const charCode = string.charCodeAt(0);
    return charCode >= 0x30 && charCode <= 0x39
        ? `\\x${charCode.toString(16)}${coolCmd(string.slice(1))}`
        : coolCmd(string);
}

| Aspekt | RegExp.escape() | Samodzielna (ulepszona) |

|---------------------|------------------|-------------------------|

| Cyfry na początku | \x32 | \x32 |

| Litery łacińskie | \x61 | Brak |

| Spacje/@ | \x20/\x40 | Brak |

| Wydajność | Natywna | Oparta na RegExp |

Zalecenia dotyczące użycia

  • Dla nowego kodu: Używaj RegExp.escape() z polyfillem dla starszych środowisk.
  • Tryb Unicode: Zawsze dodawaj flagę u — wykrywa błędy na etapie parsowania.
  • ESLint: Włącz regułę @eslint/regexp/no-octal-escape i require-unicode-regexp.
// Polyfill nie jest obowiązkowy, ale przydatny
const polyfill = () => {
  RegExp.escape = RegExp.escape || function(s) {
    return s.replace(/[-\[\]\/{}()\*+?\.\\^$\|]/g, '\\$&');
    // Dokończyć w razie potrzeby
  };
};

Co ważne

  • RegExp.escape() ekranuje cyfry/litery dla konkatenacji RegExp, spacje — na zapas.
  • Bez flagi u błędy są maskowane; z flagą — SyntaxError na parsowaniu.
  • Samodzielne funkcje są przestarzałe: migruj na natywną z polyfillem.
  • Unikaj \cX — legacy, zastąp jawnych kodami.
  • Flaga x (ignorowanie spacji) mało prawdopodobna.

— Editorial Team

Advertisement 728x90

Czytaj dalej