Hua*_*ang 22 javascript regex serialization json anonymous-function
鉴于这样的块:
var foo = {"regexp":/^http:\/\//,
"fun":function(){},
}
Run Code Online (Sandbox Code Playgroud)
将它存储在JSON中的正确方法是什么?
Ank*_*wal 33
您必须将RegExp存储为JSON对象中的字符串.然后,您可以从字符串构造一个RegExp对象:
// JSON Object (can be an imported file, of course)
// Store RegExp pattern as a string
// Double backslashes are required to put literal \ characters in the string
var jsonObject = { "regex": "^http:\\/\\/" };
function fun(url) {
var regexp = new RegExp(jsonObject.regex, 'i');
var match;
// You can do either:
match = url.match(regexp);
// Or (useful for capturing groups when doing global search):
match = regexp.exec(url);
// Logic to process match results
// ...
return 'ooga booga boo';
}
Run Code Online (Sandbox Code Playgroud)
至于函数:无论如何它们不应该用JSON或XML表示.函数可以定义为JS中的对象,但其主要目的仍然是封装一系列命令,而不是作为基本数据的包装器.
你可以这样做......
JSONEX = {
stringify: function(obj){
var jsonified = {}
// loop through object and write string and type to newly stored data structure
for(i in obj)
jsonified[i] = {
// some voodoo to determine the variable type
type: Object.prototype.toString.call(obj[i]).split(/\W/)[2],
value: obj[i].toString()
}
return JSON.stringify(jsonified)
},
parse: function(json){
objectified = {}
obj = JSON.parse(json)
// loop through object, and handle parsing of string according to type
for(i in obj)
if(obj[i].type == "RegExp"){
var m = obj[i].value.match(/\/(.*)\/([a-z]+)?/)
objectified[i] = new RegExp(m[1],m[2]);
} else if(obj[i].type == "String"){
objectified[i] = obj[i].value
} else if(obj[i].type == "Function"){
// WARNING: this is more or less like using eval
// All the usual caveats apply - including jailtime
objectified[i] = new Function("return ("+obj[i].value+")")();
}
// ADD MORE TYPE HANDLERS HERE ...
return objectified
}
}
Run Code Online (Sandbox Code Playgroud)
myThing = {
regex: new RegExp("123","g"),
text: "good",
func: function(x){
return x * x
}
}
json = JSONEX.stringify(myThing)
// "{"regex":{"type":"RegExp","value":"/123/g"},"text":{"type":"String","value":"good"},"func":{"type":"Function","value":"function (x) {\n return x * x;\n}"}}"
obj = JSONEX.parse(json)
// native object representing original object
Run Code Online (Sandbox Code Playgroud)
几乎是一个很好的解决方案,但不适用于正则表达式(无论如何)
// doing this: jsonPlus.stringify(myThing)
// just stores `regex` as an empty object
Run Code Online (Sandbox Code Playgroud)
对我来说,将两者存储为对象似乎是最好的:
{
"regexp": {
"body": "^http:\\/\\/",
"flags": ""
},
"fun": {
"args": [],
"body": ""
}
}
Run Code Online (Sandbox Code Playgroud)
对于存储正则表达式已经有很多很好的答案:将它们存储为原始字符串,以便可以使用RegExp构造函数从字符串创建实际的正则表达式。
我的补充是要记住标志。OP 可能不需要它,但它肯定必须得到解决。RegExp构造函数将字符串形式的标志作为其第二个参数。因此 JSON 存储的正则表达式的约定是:
interface JSONStoredRegExp {
body: string; // "" (empty string) for empty regexp
flags: string; // "" (empty string) for zero flags
}
Run Code Online (Sandbox Code Playgroud)
...例如,这个 JSON:
{
"regexp": {
"body": "abc",
"flags": "gi"
}
}
Run Code Online (Sandbox Code Playgroud)
...会产生这个正则表达式:
{
"regexp": {
"body": "^http:\\/\\/",
"flags": ""
},
"fun": {
"args": [],
"body": ""
}
}
Run Code Online (Sandbox Code Playgroud)
interface JSONStoredRegExp {
body: string; // "" (empty string) for empty regexp
flags: string; // "" (empty string) for zero flags
}
Run Code Online (Sandbox Code Playgroud)
除非给定的函数是纯函数,否则通过 JSON 传输它对我来说似乎很奇怪。此外,这种算法的代码可能与除 JavaScript 之外的任何语言都不兼容。
无论如何,如果仍然需要这样做,我会推荐相同的方法:将函数作为对象而不是字符串传递。还可以使用Function构造函数从序列化的参数列表和主体创建函数。
interface JSONStoredFunction {
args: string[]; // [] (empty array) for zero arguments
body: string; // "" (empty string) for no-op function
}
Run Code Online (Sandbox Code Playgroud)
Function构造函数将 body 作为最后一个参数,并且每个参数都必须单独传递;所以这个 JSON:
{
"fun": {
"args": [ "x", "y" ],
"body": "return x + y;"
}
}
Run Code Online (Sandbox Code Playgroud)
...将产生这个函数:
{
"regexp": {
"body": "abc",
"flags": "gi"
}
}
Run Code Online (Sandbox Code Playgroud)
RegExp(json.regexp.body, json.regexp.flags);
Run Code Online (Sandbox Code Playgroud)
... 使用扩展运算符可能不方便。在这种情况下,使用.apply可能会有所帮助:
/abc/gi
Run Code Online (Sandbox Code Playgroud)