Échappement dans RegExp.escape() : Pourquoi les lettres, les chiffres et les espaces deviennent des codes \x
La fonction RegExp.escape(), introduite dans les navigateurs en 2025, échappe non seulement les métacaractères regex mais aussi les lettres latines, les chiffres initiaux, les espaces et les signes de ponctuation comme @. Cela la distingue des fonctions d'échappement artisanales traditionnelles, qui ignoraient de tels caractères. La norme ECMAScript exige cela pour prévenir les erreurs lors de la concaténation de RegExp.
Raisons de l'échappement des chiffres et des lettres
Les chiffres initiaux sont échappés pour éviter leur interprétation comme numéros de groupes de capture ou codes octaux. Les lettres latines assurent une gestion correcte des séquences d'échappement comme \c.
Exemple avec un chiffre :
p = '2'
new RegExp('()\\1' + RegExp.escape(p)).source // ()\\1\\x32
new RegExp('()\\1' + p).source // ()\\12
Sans échappement, \12 fait référence au 12e groupe ou au caractère de code octal 12. Avec l'échappement, cela correspond au groupe 1 suivi du caractère 2.
Exemple avec une lettre :
p = 'a'
new RegExp('\\c' + RegExp.escape(p)).source // \\c\\x61
new RegExp('\\c' + p).source // \\ca
\ca est interprété comme un caractère de contrôle (code 1), tandis que \c\x61 est la séquence \c suivie de a. En mode Unicode (u ou v), de telles constructions déclenchent une SyntaxError, simplifiant le débogage.
Espaces et signes de ponctuation : Protection préventive
La norme n'explique pas l'échappement des espaces et des caractères comme @. Le dépôt TC39 note que tous les caractères susceptibles de déclencher un « context escape » à l'avenir sont échappés. Cela restreint l'entrée et la sortie de contexte aux seuls espaces ou signes de ponctuation ASCII.
Cette approche est controversée : elle ajoute une surcharge sans nécessité actuelle. La proposition pour un drapeau x afin d'ignorer les espaces blancs est bloquée au stade 1 sur 4.
Comparaison avec les fonctions artisanales
Fonction d'échappement classique de MDN (2020) :
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\\]\\]/g, '\\$&');
}
Elle couvre les métacaractères mais pas les chiffres ou les lettres. Une version améliorée qui échappe les chiffres initiaux et les tirets :
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);
}
| Aspect | RegExp.escape() | Personnalisée (améliorée) |
|--------------------|------------------|---------------------------|
| Chiffres initiaux | \x32 | \x32 |
| Lettres latines | \x61 | Non |
| Espaces/@ | \x20/\x40 | Non |
| Performance | Natif | Basée sur RegExp |
Recommandations d'utilisation
- Pour le nouveau code : Utilisez
RegExp.escape()avec un polyfill pour les anciens environnements. - Mode Unicode : Ajoutez toujours le drapeau
u— il détecte les erreurs au moment de l'analyse. - ESLint : Activez la règle
@eslint/regexp/no-octal-escapeetrequire-unicode-regexp.
// Polyfill non requis, mais utile
const polyfill = () => {
RegExp.escape = RegExp.escape || function(s) {
return s.replace(/[-[\]\/{}()\*+?\.\\^$\|]/g, '\\$&');
// Étendre si nécessaire
};
};
Points clés
- RegExp.escape() échappe les chiffres/lettres pour la concaténation de RegExp, les espaces par précaution.
- Sans le drapeau
u, les erreurs sont masquées ; avec lui, vous obtenez une SyntaxError au moment de l'analyse. - Les fonctions artisanales sont dépassées : migrez vers la version native avec un polyfill.
- Évitez
\cX— c'est obsolète ; utilisez des codes explicites à la place. - Le drapeau
x(ignorer les espaces blancs) est improbable.
— Editorial Team
Aucun commentaire pour le moment.