javascript - what - Serialización de RegExp
what is json (6)
Por lo tanto, me interesó encontrar que JSON.stringify
reduce un RegExp a un objeto-literal vacío ( fiddle ):
JSON.stringify(/^[0-9]+$/) // "{}"
¿Se espera este comportamiento? Me doy cuenta de que un RegExp es un objeto sin propiedades para serializar. Dicho esto, las fechas también son objetos; sin embargo, JSON.stringify()
arregla para producir una cadena significativa:
JSON.stringify(new Date) // "2014-07-03T13:42:47.905Z"
Hubiera esperado que JSON le diera a RegExp la misma consideración usando RegExp.prototype. toString()
toString()
.
Así es como resolví este problema:
Serializa como una cadena:
var pattern = /foobar/i;
var serialized = JSON.stringify(pattern.toString());
Luego rehidratarlo usando otro regex:
var fragments = serialized.match(///(.*?)//([gimy])?$/);
var rehydrated = new RegExp(fragments[1], fragments[2] || '''');
Preserva el patrón y las banderas - ¡espero que esto ayude a alguien!
Creo que un buen enfoque sería algo como esto:
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"}
Sí, porque no hay representación canónica para un objeto RegExp en JSON. Por lo tanto, es sólo un objeto vacío.
edit - bueno es 2018 ahora; Las respuestas que sugieren soluciones con .toJSON()
etc., probablemente estén bien, aunque agregaría el método al prototipo con
Object.defineProperty(RegExp.prototype, "toJSON", {
value: RegExp.prototype.toString
});
y así. Eso garantiza que el nombre de la función no sea enumerable, lo que hace que el parche de mono sea más higiénico.
Si alguien estaría interesado, hay una buena solución. No creo que el comportamiento actual sea correcto. Por ejemplo, la instancia de Date
no se serializa para vaciar un objeto como RegExp
, aunque es un object
y tampoco tiene representación 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"}"
Tanto JSON.stringify como JSON.stringify pueden personalizarse para realizar una serialización y deserialización personalizadas utilizando los argumentos del replacer
y el revisor.
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));
Solo tienes que crear tu propio formato de serialización.
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)