我有以下示例查询,它们表示复杂程度不同的对象:
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));
});
请注意,如果运行此命令,则解析器将在最终测试字符串的char 35处收到一个错误:不关闭'}'。
关于javascript - 将字符串解析为对象(自定义格式),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31564047/