RegExp的序列化

28 javascript json stringify

所以,我有兴趣发现JSON.stringify将RegExp简化为空对象 - 文字(小提琴):

JSON.stringify(/^[0-9]+$/) // "{}"
Run Code Online (Sandbox Code Playgroud)

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

JSON.stringify(new Date) // "2014-07-03T13:42:47.905Z"
Run Code Online (Sandbox Code Playgroud)

我希望JSON能够通过使用给予RegExp相同的考虑.JSON.stringify

ten*_*its 39

如果有人会感兴趣,有一个很好的解决方法.我不认为,目前的行为是正确的.例如,Date实例未被序列化为空对象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"}"
Run Code Online (Sandbox Code Playgroud)

  • @matthoiland,我总是使用它,并且我不知道任何实际的用例,当这不能使用或导致未定义的行为时.但正如你所看到的,它扩展了RegExp的原型_虽然你可以通过`Object.defineProperty`扩展它,使它不可枚举(但你曾经迭代过regexp实例吗?)_; 并且它还会更改默认为json行为,因此这个主题可以是推测性的,但根据我的经验,我发现这种方法并且这种行为是正确的. (5认同)
  • 很好,我不知道[`toJSON()`](https://developer.mozilla.org/en-US/docs/JSON#toJSON()_method). (3认同)
  • 我认为他们应该支持这一点.将此作为JSON解析器/字符串化器的默认行为是很有意义的. (3认同)
  • @goofballLogic,你不能这样做:`new RegExp(x.toString())`,因为`toString`创建RegExp文字表示法,它有尾随正斜杠,并且也以正斜杠结尾,可选地后跟正则表达式标志: `/REGEXP_STRING/FLAGS`。因此 `new RegExp("foo", "i").toString()` 会生成:“/foo/i”字符串。考虑我的编辑:https://gist.github.com/tenbits/ec7f0155b57b2d61a6cc90ef3d5f8b49 (2认同)
  • @tenbits,是的.我将避免使用这种模式,因为人们毫无疑问会犯这样的错误,即假设该字符串可以被RegExp构造函数使用. (2认同)

Fab*_*obs 27

无论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));
Run Code Online (Sandbox Code Playgroud)

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


Poi*_*nty 18

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

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

Object.defineProperty(RegExp.prototype, "toJSON", {
  value: RegExp.prototype.toString
});
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为,因为它已经在javascript中有一个文字表示,这将很好地转换为JSON; 我想不是. (2认同)
  • @tgoneil 这不是“错误”;JSON 规范根本不包括正则表达式作为原始值类型。它也不包括日期和其他各种内容。 (2认同)

pro*_*yup 5

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

将其序列化为字符串:

var pattern = /foobar/i;
var serialized = JSON.stringify(pattern.toString());
Run Code Online (Sandbox Code Playgroud)

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

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

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


tin*_*tin 5

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

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"}
Run Code Online (Sandbox Code Playgroud)