Home > Net >  What is the most efficient way to store an object containing regular expressions: json or xml?
What is the most efficient way to store an object containing regular expressions: json or xml?

Time:11-11

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
}
  • Related