Javascript RegExp的序列化
因此,我感兴趣的是发现Javascript RegExp的序列化,javascript,json,stringify,Javascript,Json,Stringify,因此,我感兴趣的是发现JSON.stringify将RegExp减少为空对象literal(): 这是预期的行为吗?我意识到RegExp是一个没有要序列化的属性的对象。也就是说,日期也是对象;然而JSON.stringify()成功地生成了一个有意义的字符串: JSON.stringify(new Date) // "2014-07-03T13:42:47.905Z" 我希望JSON会通过使用RegExp.prototype.是,给RegExp同样的考虑,因为JSON中没有RegExp对象的规
JSON.stringify
将RegExp减少为空对象literal():
这是预期的行为吗?我意识到RegExp是一个没有要序列化的属性的对象。也就是说,日期也是对象;然而JSON.stringify()
成功地生成了一个有意义的字符串:
JSON.stringify(new Date) // "2014-07-03T13:42:47.905Z"
我希望JSON会通过使用
RegExp.prototype.
是,给RegExp同样的考虑,因为JSON中没有RegExp对象的规范表示。因此,它只是一个空对象
编辑-现在是2018年;建议使用.toJSON()
等解决方案的答案可能很好,不过我会使用
Object.defineProperty(RegExp.prototype, "toJSON", {
value: RegExp.prototype.toString
});
等等。这确保了函数名不可枚举,这使得猴子补丁更卫生。如果有人感兴趣,有一个很好的解决方法。我不认为,目前的行为是正确的。例如,
Date
实例不是像RegExp
那样序列化为空对象,尽管它是一个对象,也没有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"}"
和都可以通过使用replacer
和reviver参数进行自定义序列化和反序列化
var o={
福:“酒吧”,
re:/foo/gi
};
函数替换程序(键、值){
if(值instanceof RegExp)
返回(“_REGEXP”+value.toString());
其他的
返回值;
}
功能恢复器(键、值){
if(value.toString().indexOf(“\uu REGEXP”)==0){
var m=value.split(“\uu REGEXP”)[1]。匹配(/\/(.*)\/(.*))/;
返回新的RegExp(m[1],m[2]| |“”);
}否则
返回值;
}
log(JSON.parse(JSON.stringify(o,replacer,2),reviver))代码>以下是我解决此问题的方法:
将其序列化为字符串:
var pattern = /foobar/i;
var serialized = JSON.stringify(pattern.toString());
然后使用另一个正则表达式将其重新水化:
var fragments = serialized.match(/\/(.*?)\/([a-z]*)?$/i);
var rehydrated = new RegExp(fragments[1], fragments[2] || '');
保留图案和旗帜-希望这对某人有帮助 我认为一个好的方法应该是这样的:
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"}
我认为,既然它已经有了javascript中的文字表示,那就可以很好地转换为JSON;我想不是。是的,它是一个没有属性的对象,这就是JSON所能看到的。我想你可以把它转换成一个字符串,但它仍然不是一个真正的RegExp实例。很明显,这是一个bug@十位响应应该是答案。@tgoneil它不是一个“bug”;JSON规范只是没有将正则表达式作为基本值类型包含。它也不包括日期和其他各种内容。您应该将其转换为字符串,并在以后使用RegExp
对象unserialization@shiplu.mokadd.im我不是真的在找工作。手动序列化正则表达式很容易。是的,我知道。这就是为什么我没有回答,只做了评论。@canon真正的问题是正则表达式对象没有字符串、数字和布尔值那样具有普遍性。JSON是一种数据交换格式,因此JSON在尽可能多的语言环境中可用非常重要。将RegExp实例反序列化为具有明显不同的正则表达式机制(或没有此类机制)的语言会有问题。很好,我不知道。@matthoiland,我总是使用它,我不知道任何实际用例,当无法使用它或导致未定义的行为时。但正如您所看到的,它扩展了RegExp的原型,尽管您可以通过Object.defineProperty
对其进行扩展,以使其不可枚举(但您是否迭代过RegExp实例?);它还改变了JSON行为的默认值,所以这个主题可能是推测性的,但根据我的经验,我发现这个方法和这样的行为是正确的。我认为他们应该将其标准化。将此作为JSON解析器/字符串生成器的默认行为非常有意义。@goofballLogic,您不能这样做:new RegExp(x.toString())
,因为toString
创建了RegExp文本表示法,它有尾随的正斜杠,也以正斜杠结尾,可选后跟regexp FLAGS:/regexp\u STRING/FLAGS
。因此newregexp(“foo”,“i”).toString()产生:“/foo/i”字符串。考虑一下我的编辑:嗯,是的。我将避免使用此模式,因为人们无疑会错误地假设该字符串可由RegExp构造函数使用。我的示例与上面的示例不同,因为使用我的示例可以使用JSON.stringify/parse进行序列化/反序列化,并获得相同的regex结果。您可以通过在toJSON方法RegExp.prototype.toJSON=function(){返回this.source.toString();}代码>你甚至没有使用你想要的原型方法assigned@HutchMoore尝试JSON.stringify({rgx:regexp})
@Sagi您在其上显式调用了.source
,它返回一个stirng。这就是我所说的,很好,我觉得可以有一个js库,只用于序列化/反序列化正则表达式。doing reClone=eval(re.toString())要短得多,也更容易理解(而且有效)。我不是说你应该这样做,我是在问一个问题。有人知道eval
方法是否比这里使用的方法慢吗?这很好,我不知道JSON.stringify
的第二个参数是过滤器。使用[a-zA-Z]+
而不是[gimy]?
(当前有6个标志;也可以有多个标志……事实上,我认为全部使用它们,例如,/x/gimsuy
是有效的!)2019年是的,我认为其中一些在我回答OG时没有使用:)
var fragments = serialized.match(/\/(.*?)\/([a-z]*)?$/i);
var rehydrated = new RegExp(fragments[1], fragments[2] || '');
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"}