[英]What grammar is this?
我必须解析包含变量值对组的文档,这些变量值对被序列化为字符串,例如:
4^26^VAR1^6^VALUE1^VAR2^4^VAL2^^1^14^VAR1^6^VALUE1^^
以下是不同的元素:
组 ID:
4 ^26^VAR1^6^VALUE1^VAR2^4^VAL2^^ 1 ^14^VAR1^6^VALUE1^^
每组的字符串表示长度:
4^ 26 ^VAR1^6^VALUE1^VAR2^4^VAL2^^1^ 14 ^VAR1^6^VALUE1^^
其中一组:
4^26^VAR1^6^VALUE1^VAR2^4^VAL2^^1^14 ^VAR1^6^VALUE1^^
变量:
4^26^ VAR1 ^6^VALUE1^ VAR2 ^4^VAL2^^1^14^ VAR1 ^6^VALUE1^^
值的字符串表示的长度:
4^26^VAR1^ 6 ^VALUE1^VAR2^ 4 ^VAL2^^1^14^VAR1^ 6 ^VALUE1^^
价值观本身:
4^26^VAR1^6^ VALUE1 ^VAR2^4^ VAL2 ^^1^14^VAR1^6^ VALUE1 ^^
变量仅由字母数字字符组成。 不对这些值进行任何假设,即它们可能包含任何字符,包括^
。
这种语法有名字吗? 是否有可以处理这种混乱的解析库?
到目前为止,我正在使用自己的解析器,但由于我需要检测和处理损坏的序列化,代码看起来相当混乱,因此我对可以减轻负担的解析器库提出了问题。
处理它的最简单方法是注意有两个嵌套级别以相同的方式工作。 模式非常简单:
id^length^content^
在外层,这会产生一组组。 在每个组内, content
遵循完全相同的模式,只是这里的id
是变量名, content
是变量值。
因此,您只需要编写一次该逻辑,就可以使用它来解析两个级别。 只需编写一个 function 将字符串分解为id
/ content
对列表。 调用一次以获取组,然后循环遍历它们,为每个content
再次调用它以获取该组中的变量。
将其分解为这些步骤,首先我们需要一种从字符串中获取“令牌”的方法。 这个 function 使用三种方法返回 object,以确定我们是否在“文件末尾”,并获取下一个分隔或计数的 substring:
var tokens = function(str) {
var pos = 0;
return {
eof: function() {
return pos == str.length;
},
delimited: function(d) {
var end = str.indexOf(d, pos);
if (end == -1) {
throw new Error('Expected delimiter');
}
var result = str.substr(pos, end - pos);
pos = end + d.length;
return result;
},
counted: function(c) {
var result = str.substr(pos, c);
pos += c;
return result;
}
};
};
现在我们可以方便地编写可重用的解析 function:
var parse = function(str) {
var parts = {};
var t = tokens(str);
while (!t.eof()) {
var id = t.delimited('^');
var len = t.delimited('^');
var content = t.counted(parseInt(len, 10));
var end = t.counted(1);
if (end !== '^') {
throw new Error('Expected ^ after counted string, instead found: ' + end);
}
parts[id] = content;
}
return parts;
};
它构建了一个 object,其中键是 ID(或变量名)。 我假设他们有名字,顺序不重要。
然后我们可以在两个级别使用它来创建 function 来完成整个工作:
var parseGroups = function(str) {
var groups = parse(str);
Object.keys(groups).forEach(function(id) {
groups[id] = parse(groups[id]);
});
return groups;
}
对于您的示例,它会生成此 object:
{
'1': {
VAR1: 'VALUE1'
},
'4': {
VAR1: 'VALUE1',
VAR2: 'VAL2'
}
}
我不认为为此创建语法是一项微不足道的任务。 但另一方面,简单直接的方法并不难。 您知道每个关键字符串的相应字符串长度。 所以你只需根据这些长度分开你的字符串..
你在哪里看到问题?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.