Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我可以用JSON存储RegExp和函数吗?_Javascript_Regex_Json_Serialization_Anonymous Function - Fatal编程技术网

Javascript 我可以用JSON存储RegExp和函数吗?

Javascript 我可以用JSON存储RegExp和函数吗?,javascript,regex,json,serialization,anonymous-function,Javascript,Regex,Json,Serialization,Anonymous Function,给定这样一个块: var foo = {"regexp":/^http:\/\//, "fun":function(){}, } 用JSON存储它的正确方法是什么?你不能。JSON仅用于数据,不用于代码。除非可以先将函数转换为字符串,否则无法传输函数。在核心JSON中,没有;只允许原语值(字符串/数字/布尔值/空)、数组和对象。以上所有答案都是正确的,您可以将这部分代码保存为字符串,然后执行eval() 它不是JSON,但它是序列化的一种形式:foo.toSource()

给定这样一个块:

var foo = {"regexp":/^http:\/\//,
           "fun":function(){},
}

用JSON存储它的正确方法是什么?

你不能。JSON仅用于数据,不用于代码。除非可以先将函数转换为字符串,否则无法传输函数。

在核心JSON中,没有;只允许原语值(字符串/数字/布尔值/空)、数组和对象。

以上所有答案都是正确的,您可以将这部分代码保存为字符串,然后执行
eval()


它不是JSON,但它是序列化的一种形式:
foo.toSource()
给出了一个字符串表示:
“({regexp://^http:\\/\\//,fun:(function(){})})”
。使用
bar=eval(foo.toSource())为一个新对象分配一个正则表达式和一个函数到
bar


我不知道它得到了多大的支持。有几个网站提到它只是壁虎,尽管它们已经两岁了。我目前只能访问Firefox,因此您可以测试它是否在您想要支持的浏览器(可能是IE、Chrome、Safari和Opera)中工作。

您必须将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';
}

至于函数:无论如何,它们不应该用JSON或XML表示。在JS中,函数可以定义为对象,但它的主要用途仍然是封装一系列命令,而不是用作基本数据的包装器。

您可以这样做

方法 用法
请注意 几乎是一个很好的解决方案,但不适用于正则表达式(对我来说)


我已经使用并推荐雅虎的npm软件包。它可以专门用函数和正则表达式序列化JSON,并处理其他情况

从他们的文档中:

var serialize = require('serialize-javascript');

const serialized = serialize({
    str  : 'string',
    num  : 0,
    obj  : {foo: 'foo'},
    arr  : [1, 2, 3],
    bool : true,
    nil  : null,
    undef: undefined,

    fn: function echo(arg) { return arg; },
    re: /([^\s]+)/g
});
产生

'{"str":"string","num":0,"obj":{"foo":"foo"},"arr":[1,2,3],"bool":true,"nil":null,"fn":function echo(arg) { return arg; },"re":/([^\\s]+)/g}'
它可以用水来补充水分

const obj = JSON.parse(serialized)
这可以通过查看它们的TL来验证。

TL;博士: 对我来说,将两者都存储为对象似乎是最好的:

{
    "regexp": {
        "body": "^http:\\/\\/",
        "flags": ""
    },
    "fun": {
        "args": [],
        "body": ""
    }
}

正则表达式: 存储regexp已经有很多很好的答案:将它们存储为原始字符串,这样就可以使用构造函数从字符串创建实际的regexp

我的补充是要记住国旗。OP可能不需要它,但它肯定需要解决。构造函数将字符串形式的标志作为其第二个参数。因此,JSON存储的regexp的契约是:

interface JSONStoredRegExp {
    body: string; // "" (empty string) for empty regexp
    flags: string; // "" (empty string) for zero flags
}
。。。例如,这个JSON:

{
    "regexp": {
        "body": "abc",
        "flags": "gi"
    }
}
{
    "fun": {
        "args": [ "x", "y" ],
        "body": "return x + y;"
    }
}
。。。将生成此regexp:

RegExp(json.RegExp.body,json.RegExp.flags);
/abc/gi
功能: 除非给定的函数是纯函数,否则通过JSON传输它对我来说似乎很奇怪。此外,这种算法的代码可能与JavaScript以外的任何语言都不兼容

无论如何,如果仍然需要这样做,我建议使用相同的方法:将函数作为对象而不是字符串进行传递。还可以使用构造函数从参数和主体的序列化列表创建函数

interface JSONStoredFunction {
    args: string[]; // [] (empty array) for zero arguments
    body: string; // "" (empty string) for no-op function
}
构造函数将body作为其最后一个参数,每个参数都必须单独传递;所以这个JSON:

{
    "regexp": {
        "body": "abc",
        "flags": "gi"
    }
}
{
    "fun": {
        "args": [ "x", "y" ],
        "body": "return x + y;"
    }
}
。。。将产生此功能:

函数(…json.fun.args,json.fun.body);
匿名函数(x,y){返回x+y;}
使用
可能不方便。在这种情况下,使用
.apply
可能有助于:

Function.apply(null,json.fun.args.concat(json.fun.body));

有很好的移动方式可供使用 一些新的JSON超集,包含许多JSON中非法的东西

{
  // comments
  unquoted: 'and you can quote me on that',
  singleQuotes: 'I can use "double quotes" here',
  lineBreaks: "Look, Mom! \
No \\n's!",
  hexadecimal: 0xdecaf,
  leadingDecimalPoint: .8675309, andTrailing: 8675309.,
  positiveSign: +1,
  trailingComma: 'in objects', andIn: ['arrays',],
  "backwardsCompatible": "with JSON",
}


github:

除非您已经明确地将字符串与“安全”模式(无论是通过regexp或解析器还是其他方式)匹配,否则不要使用eval,这是非常重要的——这就是JSON如此简单的原因之一;它可以被安全地解析。regexp可能是可消毒的(但不容易);函数几乎肯定不是,并且通过Godel定理或类似技术可以证明。一般不要使用eval(请参阅我在Daan回答中的评论)@JasonS我知道这一点,这只是一种方法,Huang Wants这一回答没有对这样做的安全影响提出任何警告。如果您在答案本身而不是在注释中添加警告,那么这将是一个正确但危险的回答。嘿,这真的很酷,但是如果值是对象,JSONEX.stringify会给出
{“type”:“Object”,“value”:“[Object Object]”}
。例如:
var a={b:{c:'hello world'}
有一条注释
//在这里添加更多类型处理程序…
这就是对象处理程序应该去的地方。这是一个关于如何制作解决方案的解释,而不是一个库,尽管如果是这样的话那就太好了<代码>[对象对象]
-Internet Explorer再次罢工?包括“监禁时间”。。那很好。英雄联盟所以必须将RegExp标志(例如:g、m和i)存储在JSON中的单独字符串中?
{
    "fun": {
        "args": [ "x", "y" ],
        "body": "return x + y;"
    }
}
{
  // comments
  unquoted: 'and you can quote me on that',
  singleQuotes: 'I can use "double quotes" here',
  lineBreaks: "Look, Mom! \
No \\n's!",
  hexadecimal: 0xdecaf,
  leadingDecimalPoint: .8675309, andTrailing: 8675309.,
  positiveSign: +1,
  trailingComma: 'in objects', andIn: ['arrays',],
  "backwardsCompatible": "with JSON",
}