2010-03-08 35 views

回答

1

如何將字符串轉換使用JSON爲對象而不EVAL簡單的例子:

var txt='[\'one\',\'two\']'; 

    var re1='(\\[)'; // Any Single Character 1 
    var re2='(\\\'.*?\\\')'; // Single Quote String 1 
    var re3='(,)'; // Any Single Character 2 
    var re4='(\\\'.*?\\\')'; // Single Quote String 2 
    var re5='(\\])'; // Any Single Character 3 

    var p = new RegExp(re1+re2+re3+re4+re5,["i"]); 
    var m = p.exec(txt); 
    if (m != null) 
    { 
     var c1=m[1]; 
     var s1=m[2]; 
     var c2=m[3]; 
     var s2=m[4]; 
     var c3=m[5]; 

     return [s1, s2]; 
    } 
    return null; 

是這樣一個可怕的方式做到這一點,但它做什麼,它聲稱該字符串:P

+0

你知道......技術上你的JSON字符串的例子是無效的JSON。 :-p – 2010-05-24 19:16:00

+0

我不想在這裏做得很正確,只是給他正確的方向。也是我返回一個哈希不是一個數組 – mkoryak 2010-05-24 19:17:37

9

JSON有一個well defined grammar這是用來構造一棵樹,然後轉換爲一個對象。

+0

但是如何樹轉換對象? – 2010-05-24 18:47:38

+1

@Fedor - 您所要求的等同於「JSON解析器如何實現」...... – 2010-05-24 19:04:25

+0

@Fedor - 如何實現eval? – orip 2010-05-24 19:12:28

2

我不知道具體細節,但並不是很難。只是讀取字符和子字符串的一個聰明的組合,解釋它們的意思,並建立一個數據陣列,而你這樣做。像其他解析器一樣。

2

沒有什麼祕密。你認爲eval()是如何實現的?它使用了與必須解析JSON數據相同的技術,即有效地重新實現eval()的一部分。

0

JSON是原生表示的數據。它只是JavaScript內置對象格式的創造性實現。作爲本地的,它不需要被「解析」(在程序員需要擔心這樣做的意義上)。

+0

你在說什麼,eval()是適用於JSON的解析器。這是真的,但這不是OP的內容。 – 2010-03-08 16:48:21

+0

我從來沒有說過。 – 2010-03-08 17:03:06

3

獲取道格拉斯克羅克福德的書,Javascript:好部件。附錄E包括實現JSON解析器的代碼。它不使用eval。

2

看看我的解析器是一個好主意。這並不完美,但代碼很容易遵循。

public static JsonStructure Parse(string jsonText) 
{ 
    var result = default(JsonStructure); 
    var structureStack = new Stack<JsonStructure>(); 
    var keyStack = new Stack<string>(); 
    var current = default(JsonStructure); 
    var currentState = ParserState.Begin; 
    var key = default(string); 
    var value = default(object); 

    foreach (var token in Lexer.Tokenize(jsonText)) 
    { 
     switch (currentState) 
     { 
      case ParserState.Begin: 
       switch (token.Type) 
       { 
        case TokenType.BeginObject: 
         currentState = ParserState.Name; 
         current = result = new JsonObject(); 
         break; 
        case TokenType.BeginArray: 
         currentState = ParserState.Value; 
         current = result = new JsonArray(); 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      case ParserState.Name: 
       switch (token.Type) 
       { 
        case TokenType.String: 
         currentState = ParserState.NameSeparator; 
         key = (string)token.Value; 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      case ParserState.NameSeparator: 
       switch (token.Type) 
       { 
        case TokenType.NameSeparator: 
         currentState = ParserState.Value; 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      case ParserState.Value: 
       switch (token.Type) 
       { 
        case TokenType.Number: 
        case TokenType.String: 
        case TokenType.True: 
        case TokenType.False: 
        case TokenType.Null: 
         currentState = ParserState.ValueSeparator; 
         value = token.Value; 
         break; 
        case TokenType.BeginObject: 
         structureStack.Push(current); 
         keyStack.Push(key); 
         currentState = ParserState.Name; 
         current = new JsonObject(); 
         break; 
        case TokenType.BeginArray: 
         structureStack.Push(current); 
         currentState = ParserState.Value; 
         current = new JsonArray(); 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      case ParserState.ValueSeparator: 
       var jsonObject = (current as JsonObject); 
       var jsonArray = (current as JsonArray); 
       if (jsonObject != null) 
       { 
        jsonObject.Add(key, value); 
        currentState = ParserState.Name; 
       } 
       if (jsonArray != null) 
       { 
        jsonArray.Add(value); 
        currentState = ParserState.Value; 
       } 
       switch (token.Type) 
       { 
        case TokenType.EndObject: 
        case TokenType.EndArray: 
         currentState = ParserState.End; 
         break; 
        case TokenType.ValueSeparator: 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      case ParserState.End: 
       switch (token.Type) 
       { 
        case TokenType.EndObject: 
        case TokenType.EndArray: 
        case TokenType.ValueSeparator: 
         var previous = structureStack.Pop(); 
         var previousJsonObject = (previous as JsonObject); 
         var previousJsonArray = (previous as JsonArray); 
         if (previousJsonObject != null) 
         { 
          previousJsonObject.Add(keyStack.Pop(), current); 
          currentState = ParserState.Name; 
         } 
         if (previousJsonArray != null) 
         { 
          previousJsonArray.Add(current); 
          currentState = ParserState.Value; 
         } 
         if (token.Type != TokenType.ValueSeparator) 
         { 
          currentState = ParserState.End; 
         } 
         current = previous; 
         break; 
        default: 
         throw new JsonException(token, currentState); 
       } 
       break; 
      default: 
       break; 
     } 
    } 
    return result; 
} 
相關問題