除非你願意改變你的數據格式,或者你可以找到一個簡單的方法將它變成正確的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