javascript RegExp 的序列化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12075927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 15:15:21  来源:igfitidea点击:

Serialization of RegExp

javascriptjsonstringify

提问by tenbits

So, I was interested to find that JSON.stringifyreduces a RegExp to an empty object-literal (fiddle):

所以,我很感兴趣地发现JSON.stringify将 RegExp 减少到一个空的对象字面量(小提琴):

JSON.stringify(/^[0-9]+$/) // "{}"

Is this behavior expected? I realize that a RegExp is an object with no properties to serialize. That said, dates are objects too; yet JSON.stringify()manages to produce a meaningful string:

这种行为是预期的吗?我意识到 RegExp 是一个没有要序列化的属性的对象。也就是说,日期也是对象;但JSON.stringify()设法产生一个有意义的字符串:

JSON.stringify(new Date) // "2014-07-03T13:42:47.905Z"

I would have hoped that JSON would give RegExp the same consideration by using RegExp.prototype.toString().

我希望 JSON 能够通过使用.RegExp.prototype.toString()

采纳答案by Pointy

Yes, because there's no canonical representation for a RegExp object in JSON. Thus, it's just an empty object.

是的,因为在 JSON 中没有 RegExp 对象的规范表示。因此,它只是一个空对象。

edit— well it's 2018 now; the answers suggesting solutions using .toJSON()etc are probably fine, though I'd add the method to the prototype with

编辑- 现在是 2018 年;建议使用.toJSON()等解决方案的答案可能很好,尽管我会将该方法添加到原型中

Object.defineProperty(RegExp.prototype, "toJSON", {
  value: RegExp.prototype.toString
});

and so on. That ensures that the function name isn't enumerable, which makes the monkey-patch somewhat more hygienic.

等等。这确保了函数名是不可枚举的,这使得猴子补丁更加卫生。

回答by tenbits

If somebody would be interested, there is a nice workaround. I don't think, that current behaviour is correct. For example, Dateinstance is not serialized to empty object like RegExp, though it is an objectand also has no JSON representation.

如果有人感兴趣,有一个很好的解决方法。我不认为,目前的行为是正确的。例如,Dateinstance 不会像 那样序列化为空对象RegExp,尽管它是object并且也没有 JSON 表示。

RegExp.prototype.toJSON = RegExp.prototype.toString;


// sample
var foo = { rgx: /qux$/ig, date: new Date }

JSON.stringify(foo);
//> {"rgx":"/qux$/gi","date":"2014-03-21T23:11:33.749Z"}"

回答by Fabian Jakobs

Both JSON.stringifyand JSON.parsecan be customized to do custom serialization and deserialization by using the replacerand reviver arguments.

无论JSON.stringifyJSON.parse可定制通过做自定义序列化和反序列化replacer和齐磊参数。

var o = {
  foo: "bar",
  re: /foo/gi
};

function replacer(key, value) {
  if (value instanceof RegExp)
    return ("__REGEXP " + value.toString());
  else
    return value;
}

function reviver(key, value) {
  if (value.toString().indexOf("__REGEXP ") == 0) {
    var m = value.split("__REGEXP ")[1].match(/\/(.*)\/(.*)?/);
    return new RegExp(m[1], m[2] || "");
  } else
    return value;
}

console.log(JSON.parse(JSON.stringify(o, replacer, 2), reviver));

You just have to come up with your own serialization format.

您只需要提出自己的序列化格式。

回答by probablyup

Here's how I solved this issue:

这是我解决这个问题的方法:

Serialize it as a string:

将其序列化为字符串:

var pattern = /foobar/i;
var serialized = JSON.stringify(pattern.toString());

Then rehydrate it using another regex:

然后使用另一个正则表达式再水化它:

var fragments = serialized.match(/\/(.*?)\/([a-z]*)?$/i);
var rehydrated = new RegExp(fragments[1], fragments[2] || '');

Preserves the pattern and flags - hope this helps someone!

保留图案和标志 - 希望这对某人有所帮助!

回答by Sagi

RegExp.prototype.toJSON = RegExp.prototype.toString;

var regexp = /^[0-9]+$/;
var foo = { rgx: regexp.source, date: new Date };
var stringified = JSON.stringify(foo);
new RegExp(JSON.parse(stringified).rgx)

回答by tin

I think a good approach would be something like this:

我认为一个好的方法是这样的:

function stringifyFilter(key,value) {
    if (value instanceof RegExp) {
        return value.toString();
    }

    return value;
}

var myObj = {
    text : 'Howdy ho!',
    pattern : /[a-z]+/i
}

JSON.stringify(myObj,stringifyFilter); // output: {"text":"Howdy ho!","pattern":"/[a-z]+/i"}