除非你愿意改变你的数据格式,或者你可以找到一个简单的方法将它变成正确的JSON后收到,你最好的选择是手动解析。
最简单的匹配(假定“好”的值):
On ([{ - increment parens
On)]} - decrement parens or emit error if parens is zero
On , - emit and reset the buffer if parens is zero (finish a match)
If not , - push into the output buffer
这并不与“丑”字符串的工作(报价括号,转义引号,逃脱逃脱......)。这个解析器应该正确地解析所有有效输入,同时仍然相对简单:
On ([{ - increment parens if the state is "start". Push to buffer.
On)]} - decrement parens if the state is "start" and parens is positive.
Emit an error if parens is zero. Push to buffer.
On , - emit and reset the buffer if parens is zero and the state is "start"
(finish a match). Push to buffer.
On \ - Push to buffer, and push and read the next symbol as well.
On ' - If the state is "start", change the state to "squote", and vice versa.
Push to buffer.
On " - If the state is "start", change the state to "dquote", and vice versa.
Push to buffer.
On EOF - Emit error if parens is not zero or the state is not "start".
这里是实现在Javascript草图:
function splitLiteralBodyByCommas(input){
var out = [];
var iLen = input.length;
var parens = 0;
var state = "";
var buffer = ""; //using string for simplicity, but an array might be faster
for(var i=0; i<iLen; i++){
if(input[i] == ',' && !parens && !state){
out.push(buffer);
buffer = "";
}else{
buffer += input[i];
}
switch(input[i]){
case '(':
case '[':
case '{':
if(!state) parens++;
break;
case ')':
case ']':
case '}':
if(!state) if(!parens--)
throw new SyntaxError("closing paren, but no opening");
break;
case '"':
if(!state) state = '"';
else if(state === '"') state = '';
break;
case "'":
if(!state) state = "'";
else if(state === "'") state = '';
break;
case '\\':
buffer += input[++i];
break;
}//end of switch-input
}//end of for-input
if(state || parens)
throw new SyntaxError("unfinished input");
out.push(buffer);
return out;
}
这个解析器仍然有它的缺陷:
它允许与括号等关闭parens。要解决这个问题,请使用parens
一堆符号;如果开始和结束符号不匹配,则引发异常。
它允许畸形的unicode转义的字符串。解析器接受\utest
。
它允许顶级逗号被转义。这可能不是一个错误:\,,\,
是一个有效的字符串,包含两个由未转义的逗号分隔的顶级转义逗号。
尾随的反斜杠会产生意外的输出。再次,这将通过读取我们正在转义的数据来解决。更简单的修补程序buffer += input[++i] || ''
(追加一个空字符串,而不是undefined
,但允许无效的输入
它允许各种其他无效输入:。[""'']{'\\'}"a"
仅仅是一个例子的修复需要一个更好(更COMLEX)语法,并accompanyingly更复杂的解析器
话说回来,是不是更好只使用JSON传输数据
选项1:一个真正的对象:{"text":"firstName", "css":{
...
选项2(只有你真的希望如此):一串字符串:["text:firstName, css:{
...
在这两种情况下,JSON.parse(input)
是你的朋友。
你可以修改你的数据源来产生正确的JSON吗?然后它是微不足道的...... – 2013-02-18 18:29:41
对于我的场景,分离,绑定和缓存单个绑定字符串将更有效,而不是将它们全部作为一组进行。 – bigmac 2013-02-18 18:36:57
然后以便于分开的方式存储它们。例如,作为JSON数组的字符串(如果你讨厌一组对象)。 – 2013-02-18 18:39:02