Могу ли я хранить RegExp и Function в JSON?

javascript regex json serialization anonymous-function

27829 просмотра

8 ответа

Учитывая блок, как это:

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

Как правильно хранить его в JSON?

Автор: Huang Источник Размещён: 17.05.2019 03:07

Ответы (8)


29 плюса

Вы должны сохранить 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, но ее основная цель по-прежнему заключается в том, чтобы инкапсулировать последовательность команд, а не служить оболочкой для базовых данных.

Автор: Ankit Aggarwal Размещён: 22.01.2012 12:27

10 плюса

Ты не можешь JSON только для данных, а не кода. Невозможно передать функции, если вы не можете сначала преобразовать их в строку.

Автор: Evert Размещён: 30.11.2011 03:12

7 плюса

Вы могли бы сделать что-то вроде этого ...

метод

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

    }
}

использование

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

NB

Почти хорошее решение, но не работает с регулярными выражениями (для меня все равно)

http://jsonplus.com/

// doing this: jsonPlus.stringify(myThing)
// just stores `regex` as an empty object
Автор: Billy Moon Размещён: 10.08.2012 11:51

2 плюса

В ядре JSON нет; спецификация JSON допускает только примитивные значения (string / numbers / boolean / null), а также массивы и объекты.

Автор: Jason S Размещён: 30.11.2011 03:13

2 плюса

Для тех, кто все еще ищет ответ:

с помощью плагина JSONfn вы можете сериализовать объект javascript с помощью

  • функции
  • Regexp
  • Дата

и заново создать объект из этой строки.

Документация: http://www.eslinstructor.net/jsonfn/

--Vadim

Автор: vadimk Размещён: 03.02.2014 12:05

0 плюса

Это не JSON, но это форма сериализации: foo.toSource()дает строковое представление: "({regexp:/^http:\\/\\//, fun:(function () {})})". Использование bar = eval(foo.toSource());назначает новый объект с регулярным выражением и функцией bar.

Я не знаю, насколько хорошо это поддерживается. Некоторые веб-сайты упоминают, что это только геккон, хотя им два года. В настоящее время у меня есть доступ только к Firefox, поэтому вы проверяете, работает ли он в браузерах, которые вы хотите поддерживать (например, IE, Chrome, Safari и Opera).

Автор: Daan Wilmer Размещён: 30.11.2011 03:29

0 плюса

Я использовал и рекомендовал бы пакет serialize-javascript npm от Yahoo. Он может сериализовать 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)

Это можно проверить, посмотрев на их модульные тесты .

Автор: cchamberlain Размещён: 31.08.2016 02:15

-1 плюса

Все ответы выше верны, вместо того, чтобы сохранить эту часть кода в виде строки, а затем сделать eval()

var sCode = 'var oFoo = {"regexp": new RegExp("/^http:\/\//"), "fun": function() {}}';
eval(sCode);
console.log(oFoo);
Автор: balkon_smoke Размещён: 30.11.2011 03:20
Вопросы из категории :
32x32