Est-il une RegExp.la fonction escape en Javascript?

je veux juste créer une expression régulière à partir de n'importe quelle chaîne possible.

var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);

Est-il une méthode intégrée pour qui? Si non, que les gens utilisent-ils? Ruby a RegExp.escape . Je n'ai pas l'impression d'avoir besoin d'écrire la mienne, il doit y avoir quelque chose de standard là-bas. Merci!

325
demandé sur Lance Pollard 2010-08-25 02:22:33

12 réponses

la fonction liée ci-dessus est insuffisante. Il ne parvient pas à échapper à ^ ou $ (début et fin de chaîne), ou - , qui dans un groupe de caractères est utilisé pour les gammes.

utiliser cette fonction:

RegExp.escape= function(s) {
    return s.replace(/[-\/\^$*+?.()|[\]{}]/g, '\$&');
};

bien qu'il puisse sembler inutile à première vue, échapper à - (ainsi que ^ ) rend la fonction appropriée pour échapper caractères à insérer dans une classe de caractères ainsi que le corps de le regex.

Escape / rend la fonction appropriée pour échapper des caractères à utiliser dans un js regex littéral pour plus tard eval.

comme il n'y a aucun inconvénient à échapper à l'un ou l'autre d'entre eux, il est logique de s'échapper pour couvrir des cas d'utilisation plus large.

et oui, c'est un échec décevant que cela ne fasse pas partie du JavaScript standard.

416
répondu bobince 2014-11-27 03:35:39

pour toute personne utilisant lodash, depuis v3.0.0 a _.la fonction escapeRegExp est intégrée:

_.escapeRegExp('[lodash](https://lodash.com/)');
// → '\[lodash\]\(https:\/\/lodash\.com\/\)'

et, dans le cas où vous ne voulez pas avoir besoin de la bibliothèque lodash complète, vous pouvez avoir besoin de juste cette fonction !

65
répondu gustavohenke 2016-03-09 00:04:36

la plupart des expressions ici résolvent des cas d'utilisation spécifiques.

c'est bon, mais je préfère une approche" ça marche toujours".

function regExpEscape(literal_string) {
    return literal_string.replace(/[-[\]{}()*+!<=:?.\/\^$|#\s,]/g, '\$&');
}

ceci "échappera complètement" à une chaîne littérale pour l'une des utilisations suivantes dans les expressions régulières:

  • Insertion dans une expression régulière. Par exemple: new RegExp(regExpEscape(str))
  • Insertion dans une classe de caractères. Par exemple: new RegExp('[' + regExpEscape(str) + ']')
  • Insertion dans le spécificateur de nombre entier. Par exemple: new RegExp('x{1,' + regExpEscape(str) + '}')
  • Exécution en non-JavaScript moteurs d'expressions régulières.

Caractères Spéciaux Couverts:

  • - : crée une gamme de caractères dans une classe de caractères.
  • [ / ] : commence / termine une classe de caractères.
  • { / } : commence / termine a la numération spécificateur.
  • ( / ) : commence / termine un groupe.
  • * / + / ? : spécifie le type de répétition.
  • . : correspond à tout caractère.
  • \ : échappe aux caractères, et démarre des entités.
  • ^ : spécifie le début de la zone d'appariement, et nie l'appariement dans une classe de caractères.
  • $ : indique la fin de la zone correspondante.
  • | : spécifie l'alternance.
  • # : spécifie un commentaire en mode d'espacement libre.
  • \s : ignoré en mode d'espacement libre.
  • , : sépare les valeurs dans le spécificateur de numération.
  • / : début ou fin de l'expression.
  • : : complète les types spéciaux de groupe, et une partie des classes de caractères de Perl-style.
  • ! : Négates zero-width group.
  • < / = : fait partie des spécifications du groupe à largeur nulle.

Notes:

  • / n'est pas strictement nécessaire dans toute saveur d'expression régulière. Cependant, il protège en cas de quelqu'un (frémissement) does eval("/" + pattern + "/"); .
  • , garantit que si la chaîne est censée être un entier dans le spécificateur numérique, elle causera correctement une erreur de compilation RegExp au lieu de compiler faussement silencieusement.
  • # , et \s n'ont pas besoin d'être échappés en JavaScript, mais dans beaucoup d'autres saveurs. Ils sont échappés ici au cas où l'expression régulière serait plus tard passée à un autre programme.

si vous devez également à l'avenir-preuve de l'expression régulière contre les ajouts potentiels aux capacités du moteur de regex JavaScript, je recommande d'utiliser le plus paranoid:

function regExpEscapeFuture(literal_string) {
    return literal_string.replace(/[^A-Za-z0-9_]/g, '\$&');
}

cette fonction échappe à tous les caractères sauf ceux explicitement garantis ne pas être utilisés pour la syntaxe dans les expressions régulières futures saveurs.


pour la véritable hygiène-keen, considérez ce cas de bord:

var s = '';
new RegExp('(choice1|choice2|' + regExpEscape(s) + ')');

Ce devrait compiler fine en JavaScript, mais pas dans certains autres saveurs. Si l'intention de passer à une autre saveur, le cas null de s === '' doit être vérifié indépendamment, comme ainsi:

var s = '';
new RegExp('(choice1|choice2' + (s ? '|' + regExpEscape(s) : '') + ')');
28
répondu Pi Marillion 2015-09-06 07:35:38

dans le widget autocomplete de jQueryUI (version 1.9.1) ils utilisent un regex légèrement différent (ligne 6753), voici l'expression régulière combinée avec l'approche @bobince.

RegExp.escape = function( value ) {
     return value.replace(/[\-\[\]{}()*+?.,\\^$|#\s]/g, "\$&");
}
17
répondu Pierluc SS 2012-10-31 12:30:01

Mozilla Developer's Guide to Regular Expressions fournit cette fonction d'échappement:

function escapeRegExp(string){
    return string.replace(/([.*+?^${}()|\[\]\/\])/g, "\");
}
13
répondu user113215 2014-08-07 16:30:25

rien ne devrait vous empêcher d'échapper à chaque caractère non alphanumérique:

usersString.replace(/(?=\W)/g, '\');

vous perdez un certain degré de lisibilité en faisant re.toString() mais vous gagnez beaucoup de simplicité (et de sécurité).

selon L'ECMA-262, d'une part, les expressions régulières "caractères syntaxiques" sont toujours non alphanumériques, de sorte que le résultat est sûr, et les séquences d'échappement spéciales( \d , \w , \n ) sont toujours Alphanumériques de sorte qu'aucune fausse échappée de contrôle ne sera produite.

8
répondu daluege 2017-08-07 15:39:06

Il y a un ES7 proposition de RegExp.escape à https://github.com/benjamingr/RexExp.escape / , avec un polyfill disponible à https://github.com/ljharb/regexp.escape .

7
répondu 2015-06-15 18:29:14

C'est une version plus courte.

RegExp.escape = function(s) {
    return s.replace(/[$-\/?[-^{|}]/g, '\$&');
}

comprend les caractères non méta % , & , ' , et , , mais la spécification JavaScript RegExp le permet.

4
répondu kzh 2013-09-04 17:23:49
escapeRegExp = function(str) {
  if (str == null) return '';
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\])/g, '\');
};
1
répondu Ravi Gadhia 2018-06-28 16:08:06

XRegExp a une fonction escape:

XRegExp.escape('Escaped? <.>'); // -> 'Escaped\?\ <\.>'

plus sur: http://xregexp.com/api/#escape

0
répondu Antoine Dusséaux 2017-07-05 17:58:19

plutôt que d'échapper aux seuls caractères qui causeront des problèmes dans votre expression régulière (par exemple: une liste noire), pourquoi ne pas envisager d'utiliser une liste blanche à la place. De cette façon, chaque caractère est considéré comme étant teinté à moins qu'il ne corresponde.

pour cet exemple, supposons l'expression suivante:

RegExp.escape('be || ! be');

Ce des listes blanches de lettres, de nombre et d'espaces:

RegExp.escape = function (string) {
    return string.replace(/([^\w\d\s])/gi, '\');
}

Retourne:

"be \|\| \! be"

en mai échapper à des personnages qui n'ont pas besoin d'être échappé, mais cela n'empêche pas votre expression (peut - être quelques pénalités de temps mineures-mais il vaut la peine pour la sécurité).

0
répondu bashaus 2017-08-03 11:46:59

les fonctions dans les autres réponses sont excessives pour échapper à des expressions régulières entières (elles peuvent être utiles pour échapper à des parties d'expressions régulières qui seront ensuite concaténées en de plus grands regexps).

si vous échappez à une regexp entière et que vous en avez fini avec elle, en citant les métacharactères qui sont soit autonomes ( . , ? , + , * , ^ , $ , | , \ ), ou de lancer quelque chose ( ( , [ , { ) tout le nécessaire:

String.prototype.regexEscape = function regexEscape() {
  return this.replace(/[.?+*^$|({[\]/g, '\$&');
};

et oui, il est décevant que JavaScript n'ait pas une fonction comme celle-ci.

-1
répondu Dan Dascalescu 2014-11-28 01:32:55