181 votes

typeof pour RegExp

Existe-t-il un moyen de détecter si un objet JavaScript est une regex ?

Par exemple, je voudrais faire quelque chose comme ceci :

var t = /^foo(bar)?$/i;
alert(typeof t); //I want this to return "regexp"

Est-ce possible ?

Merci !

EDIT : Merci pour toutes les réponses. Il semble que j'ai deux très bons choix :

obj.constructor.name === "RegExp"

o

obj instanceof RegExp

Y a-t-il des avantages ou des inconvénients majeurs à l'une ou l'autre méthode ?

Merci encore !

1 votes

Voir cette réponse à une autre question concernant l'utilisation de instanceof y constructor .

1 votes

Bonjour, je ne pense pas que mettre des réponses dans votre question soit très pertinent. Veuillez envisager d'ajouter votre propre réponse si vous pensez pouvoir apporter quelque chose d'utile :)

247voto

Cleiton Points 4203

Vous pouvez utiliser instanceof opérateur :

var t = /^foo(bar)?$/i;
alert(t instanceof RegExp);//returns true

En fait, c'est presque la même chose que :

var t = /^foo(bar)?$/i;
alert(t.constructor == RegExp);//returns true

Gardez à l'esprit que, comme RegExp n'est pas un type de données primitives il n'est pas possible d'utiliser typeof opérateur qui pourrait être la meilleure option pour cette question.

Mais vous pouvez utiliser cette astuce ci-dessus ou d'autres comme type de canard vérification de par exemple, en vérifiant si cet objet possède des méthodes ou des propriétés vitales, ou par son valeur interne de la classe (en utilisant {}.toString.call(instaceOfMyObject) ).

1 votes

Génial. savez-vous ce qui est le plus rapide/le plus compatible : utiliser votre méthode instanceof ou la méthode constructor.name ? merci !

1 votes

Instanceof, bien sûr, vous pouvez le vérifier vous-même en utilisant Firebug Timing(console.time)

13 votes

Ces deux extraits de code ne sont pas identiques. Si vous insérez la ligne t.constructor = function() {}; ce qui est parfaitement légal, alors t instanceof RegExp sera toujours vrai mais t.constructor == RegExp sera fausse. Utilisation de instanceof est donc préférable.

24voto

user113716 Points 143363
alert( Object.prototype.toString.call( t ) ); // [object RegExp]

C'est la manière mentionnée dans la spécification pour obtenir la classe de l'objet.

De ECMAScript 5, section 8.6.2 Propriétés internes et méthodes des objets :

La valeur de la propriété interne [[Classe]] est définie par cette spécification pour chaque type d'objet intégré. La valeur de la propriété interne [[Class]] d'un objet hôte peut être n'importe quelle valeur de type String, sauf l'une des valeurs suivantes "Arguments", "Tableau", "Booléen", "Date", "Erreur", "Fonction", "JSON", "Math", "Nombre", "Objet", "RegExp" et "Chaîne". . La valeur d'une propriété interne [[Classe]] est utilisée en interne pour distinguer différents types d'objets. Notez que cette spécification ne fournit aucun moyen pour un programme d'accéder à cette valeur, sauf par le biais de Object.prototype.toString (voir 15.2.4.2).

Un RegExp est une classe d'objets définie dans la spécification à l'adresse suivante Section 15.10 Objets RegExp(RegularExpression) :

Un objet RegExp contient une expression régulière et les drapeaux associés.

4 votes

@Tim - Je suis presque sûr. Ce n'est pas une garantie, mais c'est la solution la plus sûre. jQuery utilise la méthode y compris pour RegExp . Je viens de faire un test rapide dans IE6 en utilisant un RegExp, et cela fonctionne (si c'est un indicateur) :o) Il semble que cette méthode soit entrée dans les spécifications de la 3e édition.

1 votes

Malheureusement, cela ne fonctionne pas dans IE avec des objets RegExp provenant d'autres Windows, pour la même raison que la fonction [object Array] ne fonctionne pas pour les tableaux. Voir jsfiddle.net/F6d8u pour une démonstration et groups.google.com/group/comp.lang.javascript/browse_frm/thread/ pour une discussion à ce sujet.

3 votes

En dehors de la dactylographie du canard, qui est d'une inexactitude irritante, c'est encore la meilleure réponse.

14voto

John Kugelman Points 108754

Donnez à la .constructor la propriété d'un tourbillon :

> /^foo(bar)?$/i.constructor
function RegExp() { [native code] }
> /^foo(bar)?$/i.constructor.name
"RegExp"
> /^foo(bar)?$/i.constructor == RegExp
true

4 votes

El constructor peut être modifié. instanceof n'a pas ce problème et constitue une meilleure solution.

1 votes

@TimDown, c'est vrai, mais instanceof ne fonctionnera pas dans tous les contextes d'exécution.

0 votes

En revanche, n'importe qui peut construire un objet dont .constructor a ce nom.

11voto

Sean Vieira Points 47080

De underscore.js

// Is the given value a regular expression?
  _.isRegExp = function(obj) {
    return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
  };

1 votes

Ils sont en train de taper dans le canard ici parce que typeof n'est pas fiable pour les regex et instanceof souffre du problème des fenêtres croisées. Je me demande pourquoi ils n'utilisent pas la réponse de @patrick dw...

3 votes

Maintenant je sais : cela ne fonctionne pas dans IE quand on examine des objets d'autres Windows.

0 votes

@Tim -- génial ... Je me demandais la même chose, mais je n'avais pas encore eu le temps de vérifier. Merci de poster la réponse ici !

3voto

werehuman Points 1140

Fonctionne dans google chrome :

x = /^foo(bar)?$/i;
x == RegExp(x); // true
y = "hello";
y == RegExp(y); // false

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X