javascript - 将字符串解析为对象(自定义格式)

标签 javascript

我有以下示例查询,它们代表不同复杂性的对象:

abc,def,ghi

abc,\def,ghi

abc,\def{ghi,jkl},mno

abc,\def{ghi,\jkl},mno

abc,\def{ghi,\jkl{mno,pqr,\stu},vwx

在上面的示例中,我仅使用了 3 个字母来表示一个单词。该单词可以是任意长度。

有两种不同类型的单词。如果一个单词以反斜杠开头,则称为边缘。如果不是,则称为字段。

字段和边可以属于边。这些是在edge{}中定义的。这是无限递归的,因此单词可以属于属于边缘的边缘,属于边缘的边缘等等。

我想解析这个字符串并将其转换为 JavaScript 对象。

这很难解释,所以举个例子可能更好..

例如 1 这应该转换为:

[
    {
        type: "field",
        val: "abc"
    },
    {
        type: "field",
        val: "def"
    },
    {
        type: "field",
        val: "ghi"
    },
]

例如 2 这应该转换为:

[
    {
        type: "field",
        val: "abc"
    },
    {
        type: "edge",
        val: "def",
        children: []
    },
    {
        type: "field",
        val: "ghi"
    }
]

例如 5 这应该转换为:

[
    {
        type: "field",
        val: "abc"
    },
    {
        type: "edge",
        val: "def",
        children: [
            {
                type: "field",
                val: "ghi"
            },
            {
                type: "edge",
                val: "jkl",
                children: [
                    {
                        type: "field",
                        val: "mno"
                    },
                    {
                        type: "field",
                        val: "pqr"
                    },
                    {
                        type: "edge",
                        val: "stu",
                        children: []
                    }
                ]
            }
        ]
    },
    {
        type: "field",
        val: "vwx"
    }
]

要做到这一点,我认为它必须逐个字符地爬行字符串,找出它当前正在查看的内容,并在运行过程中构建/遍历对象。也许我可以使用某种递归正则表达式?

对于如何最好地做到这一点有什么想法吗?任何想法、概念等都将不胜感激。

最佳答案

我建议编写语法并实现 recursive descent parser 。它们非常简单。

var parse = function(s){

    var i = 0;

    var peek = function(c){
        return s[i] === c;
    };

    var next = function(c){
        var found = s[i];
        if(c && s[i] !== c){
            throw 'expected ' + c + ' at char ' + i + ': ' + s.slice(i,20);
        }
        i += 1;
        return found;
    };

    var word = function(){
        var w = '';
        if(!/[a-z]/.test(s[i])){
            throw 'expected a word at char ' + i + ': ' + s.slice(i,20);
        }
        while(s[i] && /[a-z]/.test(s[i])){
            w += s[i];
            i += 1;
        }
        return w;
    };

    var edge = function(){
        next('\\');
        var val = word();
        var e = {
            type: 'edge',
            val: val
        };
        if(peek('{')){
            next('{');
            e.children = fields_or_edges();
            next('}');
        }
        return e;
    };

    var field = function(){
        return {
            type: 'field',
            val: word()
        };
    };

    var fields_or_edges = function(){
        var stuff = [];
        var thing;
        do {
            if(peek('\\')){
                thing = edge();
            }else{
                thing = field();
            }
            stuff.push(thing);
        }while(peek(',') && next());
        return stuff;
    };

    return fields_or_edges();
};

让我们测试一下。

[
    'abc,def,ghi',
    'abc,\\def,ghi',
    'abc,\\def{ghi,jkl},mno',
    'abc,\\def{ghi,\\jkl},mno',
    'abc,\\def{ghi,\\jkl{mno,pqr,\\stu},vwx' // uncaught exception: expected } at char 35: 
].forEach(function(s){
    console.log(JSON.stringify(parse(s), null, 4));
});

请注意,如果运行此命令,解析器会在最终测试字符串中的第 35 个字符处发现一个错误:没有结束“}”。

关于javascript - 将字符串解析为对象(自定义格式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31564047/

相关文章:

javascript - 具有后备功能的 Angular html5 模式

javascript - 通过调用函数定义Javascript的对象属性

javascript - 如何解析 jQuery 值?

javascript - 如何根据特定的 JSON 对象值对数组进行计数?

javascript - 将函数转换为 jsx

javascript - 除了隐藏数据之外,将数据包装在函数调用中还有哪些优点?

javascript - 是否可以在 Canvas 中获取位置,其中 canvas 是 css 固定元素?

javascript - 事件监听器函数中的 chrome.webrequest

javascript - 发送配置数据

javascript - Socket.io : "Cannot read property ' emit' of undefined"