My Electron app needs to store into and retrieve from a sqlite db, objects like this:
{"name":"my regexp","regexp":/some\spattern/i}
(real objects are much larger and much more complex.)
I started by storing stringified object in a field, but since JSON.stringify() does not handle regular expressions and converts them to {}, I had to convert all regexps to strings, which stringify() then escapes. I end up with very convoluted code in many functions.
If anyone has solved this problem elegantly either with JSON or XML, I would love a good solution.
CodePudding user response:
You can use JSON. The JSON
functions parse
and stringify
accept a second argument to influence the process.
Here are two such functions replacer
and reviver
which you can use in your calls of JSON.parse
and JSON.stringify
:
const replacer = (key, value) => value instanceof RegExp
? [value.source, value.flags, "RegExp"]
: value;
const reviver = (key, value) => value[2] === "RegExp"
? RegExp(...value)
: value;
// Example run
let o = {"name":"my regexp","regexp":/some\spattern/i};
console.log(o);
let str = JSON.stringify(o, replacer);
let o2 = JSON.parse(str, reviver);
console.log(o2);
CodePudding user response:
I recommend JSON over XML, it's more compact, and is human readable.
Building up on @trincot's answer, here is a solution if you want to get a valid JSON string from the regex, so that it can be stored natively in browser local storage or a NoSQL database; it also makes it obvious that a string is a Regex string:
const replacer = (key, value) => value instanceof RegExp
? '/' value.source '/' value.flags : value;
const reviver = (key, value) => {
let m = (typeof value == 'string') && value.match(/^\/(.*)\/([gimous]*)$/);
if(m) {
value = new RegExp(m[1], m[2]);
}
return value;
}
let o = { "name": "foo", "num": 99, "regexp": /some\spattern/i };
console.log(o);
let str = JSON.stringify(o, replacer);
console.log(str);
let o2 = JSON.parse(str, reviver);
console.log(o2);
Output:
{
"name": "foo",
"num": 99,
"regexp": /some\spattern/i
}
{"name":"foo","num":99,"regexp":"/some\\spattern/i"}
{
"name": "foo",
"num": 99,
"regexp": /some\spattern/i
}