我有以下示例查询,它们代表不同复杂性的对象:
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/