# 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ą:
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.
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):
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-escapeirequire-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
ubłę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
Brak komentarzy.