web-dev-qa-db-ja.com

RegExpのtypeof

JavaScriptオブジェクトが正規表現であるかどうかを検出する方法はありますか?

たとえば、次のようなことをしたいと思います。

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

これは可能ですか?

ありがとう!

編集:すべての答えをありがとう。私には2つの非常に良い選択肢があるようです:

obj.constructor.name === "RegExp"

または

obj instanceof RegExp

どちらの方法にも大きな長所/短所はありますか?

再度、感謝します!

130
tau

instanceof演算子を使用できます:

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

実際、それはalmostと同じです:

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

RegExpプリミティブデータ型 ではないため、typeofを使用できないことに注意してください。この質問に対して 最良のオプション となり得る演算子。

ただし、上記のこのトリックまたはduck type checkingなどのその他のトリックを使用できます。たとえば、そのようなオブジェクトに重要なメソッドまたはプロパティがあるかどうか、または内部クラス値{}.toString.call(instaceOfMyObject)を使用)。

173
Cleiton
alert( Object.prototype.toString.call( t ) ); // [object RegExp]

これは、オブジェクトのクラスを取得するための仕様で言及されている方法です。

ECMAScript 5、セクション8.6.2オブジェクトの内部プロパティとメソッド

[[Class]]内部プロパティの値は、あらゆる種類の組み込みオブジェクトに対してこの仕様で定義されています。 Hostオブジェクトの[[Class]]内部プロパティの値は、"Arguments"、 "Array"、 "Boolean"、 "Date"、 "Error"、 "Function"のいずれかを除く任意の文字列値です。 、「JSON」、「Math」、「Number」、「Object」、「RegExp」、および「String」。 [[Class]]内部プロパティの値は、さまざまな種類のオブジェクトを区別するために内部的に使用されます。この仕様は、Object.prototype.toString(15.2.4.2を参照)を除いて、プログラムがその値にアクセスする手段を提供しないことに注意してください。

RegExpは、セクション15.10 RegExp(RegularExpression)Objectsの仕様で定義されているオブジェクトのクラスです。

RegExpオブジェクトには、正規表現と関連するフラグが含まれています。

22
user113716

.constructorプロパティを旋回:

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

nderscore.js から

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

Google Chromeで動作します:

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

これを確認する絶対的な方法はありません。これまでのところ、最良の答えは

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

しかし、このアプローチには欠点が1つあり、正規表現オブジェクトが他のウィンドウから来ている場合はfalseを返します。

0
Iman Mohamadi

次の2つの方法があります。

/^\/.*\/$/.test(/hi/) /* test regexp literal via regexp literal */
/^\/.*\/$/.test(RegExp("hi") ) /* test RegExp constructor via regexp literal */
RegExp("^/" + ".*" + "/$").test(/hi/) /* test regexp literal via RegExp constructor */
RegExp("^/" + ".*" + "/$").test(RegExp("hi") ) /* test RegExp constructor via RegExp constructor */ 

delete RegExp("hi").source /* test via deletion of the source property */
delete /hi/.global /* test via deletion of the global property */
delete /hi/.ignoreCase /* test via deletion of the ignoreCase property */
delete RegExp("hi").multiline /* test via deletion of the multiline property */
delete RegExp("hi").lastIndex /* test via deletion of the lastIndex property */

文字列リテラルが正規表現のバックスラッシュ区切り文字で区切られている場合、正規表現の自己テストは失敗します。

Object.sealまたはObject.freezeはユーザー定義のオブジェクトで実行され、そのオブジェクトには前述のすべてのプロパティもあります。deleteステートメントは偽陽性を返します。

参考文献

0
Paul Sweatte

「Regexp」はネイティブのJavascriptタイプではありません。上記の答えのほとんどは、あなたのタスクを達成する方法を教えてくれますが、その理由を教えてくれません。 理由 です。