正则表达式的字符串化?

5
当然,JSON不支持正则表达式字面量。
因此,
JSON.stringify(/foo/)

提供:

{ }

有什么解决方法吗?

4个回答

12

我认为这是最接近的:

RegExp.prototype.toJSON = function() { return this.source; };

JSON.stringify({ re: /foo/ }); // { "re": "foo" }

3
+1,但它不会给你修饰符,你需要使用 + (this.global ? "g" : "") 等方式添加修饰符。 - Blue Skies
1
就像@BlueSkies所说的那样。 :) 或者你可以使用.toString,我相信它会给你所有的东西。这个想法只是为了演示如何强制RegExps能够自己去JSON。 - Amadan
1
使用替换函数是否比修改 RegExp.prototype(并破坏封装性)更可取? - Dagg Nabbit
我个人认为这样更加清晰易懂。万一有一个正则表达式存在,如果不避免测试每个值,那就太不幸了。所以他们提供了.toJSON选项。 - Blue Skies
@DaggNabbit:是的,对于公共图书馆来说不太好(除非有很好的文档记录),但我有点怀疑这不是OP正在做的事情。不过你说得很好。 - Blue Skies
显示剩余3条评论

6
你可以向JSON.stringify传递一个自定义替换函数,并将正则表达式转换为字符串(假设该表达式是数组或对象的一部分):
JSON.stringify(value, function(key, value) {
    if (value instanceof RegExp) {
        return value.toString();
    }
    return value;
});

如果你实际上不想或者不需要创建JSON,只需调用表达式的toString()方法即可。

现在instanceof RegExp可靠吗?据我所知,一些浏览器过去将正则表达式视为Function的实例。 - Dagg Nabbit
@Dagg:我不知道那个问题,所以我不清楚。 - Felix Kling
@DaggNabbit:那是 typeof,并且是在旧版本的 Chrome 中。 - Blue Skies
@BlueSkies,可能是这样,尽管我非常确定Safari是我所想的那个案例的罪魁祸首。 - Dagg Nabbit
@DaggNabbit Safari 11+ 对于 /foo/ instanceof RegExp 返回 true。 - Christian Ulbrich

2
尽管JavaScript对象允许您将正则表达式作为值放置,但JSON不允许,因为它的目的是仅存储数据而非代码。
为了解决这个问题,您可以使用toString()方法将正则表达式转换为字符串。
var str = /([a-z]+)/.toString(); // "/([a-z]+)/"

1
你可以使用替换器函数:
JSON.stringify(/foo/, 
    function(k, v) { 
        if (v && v.exec == RegExp.prototype.exec) return '' + v; 
        else return v; 
    })

这不是一个足够完整的测试。它会混淆任何其他具有真值.source属性的对象。并且你没有提供默认返回值。 - Blue Skies
几乎了。你需要确保 v 不是 nullundefined。 ;) - Blue Skies
哇,你真是太厉害了。又修好了。而且我今天才知道 JSON.stringify 会把 undefined 转换成 null,以前从没注意过。 - Dagg Nabbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接