[转载]发布一款轻量级的JSON转换代码 – 仰光 – 博客园.
.NET FrameWork 2.0 并没有提供JSON 字符串对象化工具,因此尝试写了这个转换器, 目前已投入使用,分享一下. 实现方式是:正则 + 递归. 对需要转换的Json 字符串复杂度没有要求. 欢迎测试,并提供反馈,谢谢. 第一次运行,有点慢,估计是初使化正则占用了时间,这些正则是静态的,之后的转换会加快.
using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; namespace JsonConver { /// <summary> /// 节点枚举 /// </summary> public enum NodeType { /// <summary> /// 标识数组 /// </summary> IsArray , /// <summary> /// 标识对象 /// </summary> IsObject , /// <summary> /// 标识元数据 /// </summary> IsOriginal , /// <summary> /// 未知格式 /// </summary> Undefined } //描述Json节点 public class JsonNode { public NodeType NodeType; public List List; public Dictionary DicObject; public string Value; } /// <summary> /// json 字符串对象化 /// </summary> public class ConvertJsonObject { static string regTxt = "({0}[^{0}{1}]*(((?'Open'{0})[^{0}{1}]*)+((?'-Open'{1})[^{0}{1}]*)+)*(?(Open)(?!)){1})"; //匹配字符串(单双引号范围) static string regKeyValue = "({0}.{1}?(? //匹配元数据(不包含对象,数组) static string regOriginalValue = string.Format("({0}|{1}|{2})", string.Format(regKeyValue, "'", "*"), string.Format(regKeyValue, "\"", "*"), "\\w+"); //匹配value (包含对象数组) static string regValue = string.Format("({0}|{1}|{2})", regOriginalValue //字符 , string.Format(regTxt, "\\[", "\\]"), string.Format(regTxt, "\\{", "\\}")); //匹配键值对 static string regKeyValuePair = string.Format("\\s*(?{0}|{1}|{2})\\s*:\\s*(?{3})\\s*" , string.Format(regKeyValue, "'", "+"), string.Format(regKeyValue, "\"", "+"), "([^ :,]+)" //匹配key , regValue); //匹配value /// <summary> /// 判断是否是对象 /// </summary> static Regex RegJsonStrack1 = new Regex(string.Format("^\\{0}(({2})(,(?=({2})))?)+\\{1}$", "{", "}", regKeyValuePair), RegexOptions.Compiled); /// <summary> /// 判断是否是序列 /// </summary> static Regex RegJsonStrack2 = new Regex(string.Format("^\\[(({0})(,(?=({0})))?)+\\]$", regValue), RegexOptions.Compiled); /// <summary> /// 判断键值对 /// </summary> static Regex RegJsonStrack3 = new Regex(regKeyValuePair, RegexOptions.Compiled); //匹配value static Regex RegJsonStrack4 = new Regex(regValue, RegexOptions.Compiled); //匹配元数据 static Regex RegJsonStrack6 = new Regex(string.Format("^{0}$", regOriginalValue), RegexOptions.Compiled); //移除两端[] , {} static Regex RegJsonRemoveBlank = new Regex("(^\\s*[\\[\\{'\"]\\s*)|(\\s*[\\]\\}'\"]\\s*$)", RegexOptions.Compiled); string JsonTxt; public ConvertJsonObject(string json) { //去掉换行符 json = Regex.Replace(json, "[\r\n]", ""); JsonTxt = json; } /// <summary> /// 判断节点内型 /// </summary> ////// public NodeType MeasureType(string json) { if (RegJsonStrack1.IsMatch(json)) { return NodeType.IsObject; } if (RegJsonStrack2.IsMatch(json)) { return NodeType.IsArray; } if (RegJsonStrack6.IsMatch(json)) { return NodeType.IsOriginal; } return NodeType.Undefined; } /// <summary> /// json 字符串序列化为对象 /// </summary> ////// public JsonNode SerializationJsonNodeToObject() { return SerializationJsonNodeToObject(JsonTxt); } /// <summary> /// json 字符串序列化为对象 /// </summary> ////// public JsonNode SerializationJsonNodeToObject(string json) { json = json.Trim(); NodeType nodetype = MeasureType(json); if (nodetype == NodeType.Undefined) { throw new Exception("未知格式Json: " + json); } JsonNode newNode = new JsonNode(); newNode.NodeType = nodetype; if (nodetype == NodeType.IsArray) { json = RegJsonRemoveBlank.Replace(json, ""); MatchCollection matches = RegJsonStrack4.Matches(json); newNode.List = new List(); foreach (Match match in matches) { if (match.Success) { newNode.List.Add(SerializationJsonNodeToObject(match.Value)); } } } else if (nodetype == NodeType.IsObject) { json = RegJsonRemoveBlank.Replace(json, ""); MatchCollection matches = RegJsonStrack3.Matches(json); newNode.DicObject = new Dictionary(); string key; foreach (Match match in matches) { if (match.Success) { key = RegJsonRemoveBlank.Replace(match.Groups["key"].Value, ""); if (newNode.DicObject.ContainsKey(key)) { throw new Exception("json 数据中包含重复键, json:" + json); } newNode.DicObject.Add(key, SerializationJsonNodeToObject(match.Groups["value"].Value)); } } } else if (nodetype == NodeType.IsOriginal) { newNode.Value = RegJsonRemoveBlank.Replace(json, "").Replace("\\r\\n", "\r\n"); } return newNode; } } }
其中 JsonNode 是返回解析结果
NodeType 是枚举类型,表示当前节点是什么类型.
IsArray: JsonNode.List
IsObject:JsonNode.DicObject
IsOriginal:JsonNode.Value
Json 字符串换行请用双斜杠,如 “aa\\r\\nbb”,表示aa,bb 为相邻两行.
调用代码:
JsonConver.ConvertJsonObject jsonObj = new JsonConver.ConvertJsonObject("{'a':11,'b':[1,2,3],'c':{'a':1,'b':[1,2,3]}}"); JsonConver.JsonNode node = jsonObj.SerializationJsonNodeToObject(); if (node.NodeType == JsonConver.NodeType.IsObject) { if (node.DicObject["a"].NodeType == JsonConver.NodeType.IsOriginal) { Console.Write("key:a , value:"); Console.Write(node.DicObject["a"].Value); Console.WriteLine(); } if (node.DicObject["b"].NodeType == JsonConver.NodeType.IsArray) { Console.Write("key:b,value for first:"); Console.Write(node.DicObject["b"].List[0].Value); Console.WriteLine(); } if (node.DicObject["c"].NodeType == JsonConver.NodeType.IsObject) { if (node.DicObject["c"].DicObject["a"].NodeType == JsonConver.NodeType.IsOriginal) { Console.Write("key:c 子对象值: , value:"); Console.Write(node.DicObject["c"].DicObject["a"].Value); Console.WriteLine(); } } } Console.Read();