/// <summary> /// 获取值的长度(当Json值嵌套以"{"或"["开头时) /// </summary> private static int GetValueLength(string json, bool breakOnErr, out int errIndex) { errIndex = 0; int len = 0; if (!string.IsNullOrEmpty(json)) { CharState cs = new CharState(); char c; for (int i = 0; i < json.Length; i++) { c = json[i]; if (!SetCharState(c, ref cs)) //设置关键符号状态。 { if (!cs.jsonStart && !cs.arrayStart) //json结束,又不是数组,则退出。 { break; } } else if (cs.childrenStart) //正常字符,值状态下。 { int length = GetValueLength(json.Substring(i), breakOnErr, out errIndex); //递归子值,返回一个长度。。。 cs.childrenStart = false; cs.valueStart = 0; //cs.state = 0; i = i + length - 1; } if (breakOnErr && cs.isError) { errIndex = i; return(i); } if (!cs.jsonStart && !cs.arrayStart) //记录当前结束位置。 { len = i + 1; //长度比索引+1 break; } } } return(len); }
/* * /// <summary> * /// 获取值的长度(当Json值嵌套以"{"或"["开头时) * /// </summary> * private static int GetValueLength(bool isStrictMode, string json, bool breakOnErr, out int errIndex) * { * errIndex = 0; * int len = json.Length - 1; * if (!string.IsNullOrEmpty(json)) * { * CharState cs = new CharState(isStrictMode); * char c; * for (int i = 0; i < json.Length; i++) * { * c = json[i]; * if (!cs.IsKeyword(c))//设置关键符号状态。 * { * if (!cs.jsonStart && !cs.arrayStart)//json结束,又不是数组,则退出。 * { * break; * } * } * else if (cs.childrenStart)//正常字符,值状态下。 * { * int length = GetValueLength(isStrictMode, json.Substring(i), breakOnErr, out errIndex);//递归子值,返回一个长度。。。 * cs.childrenStart = false; * cs.valueStart = 0; * //cs.state = 0; * i = i + length - 1; * } * if (breakOnErr && cs.isError) * { * errIndex = i; * return i; * } * if (!cs.jsonStart && !cs.arrayStart)//记录当前结束位置。 * { * len = i + 1;//长度比索引+1 * break; * } * } * } * return len; * } */ /// <summary> /// 获取值的长度(当Json值嵌套以"{"或"["开头时),【优化后】 /// </summary> private static int GetValueLength(bool isStrictMode, string json, int startIndex, bool breakOnErr, out int errIndex) { errIndex = 0; int len = json.Length - 1 - startIndex; if (!string.IsNullOrEmpty(json)) { CharState cs = new CharState(isStrictMode); char c; for (int i = startIndex; i < json.Length; i++) { c = json[i]; if (!cs.IsKeyword(c)) //设置关键符号状态。 { if (!cs.jsonStart && !cs.arrayStart) //json结束,又不是数组,则退出。 { break; } } else if (cs.childrenStart) //正常字符,值状态下。 { int length = GetValueLength(isStrictMode, json, i, breakOnErr, out errIndex); //递归子值,返回一个长度。。。 cs.childrenStart = false; cs.valueStart = 0; i = i + length - 1; } if (breakOnErr && cs.isError) { errIndex = i; return(i - startIndex); } if (!cs.jsonStart && !cs.arrayStart) //记录当前结束位置。 { len = i + 1; //长度比索引+1 len = len - startIndex; break; } } } return(len); }
internal static bool IsJson(string json, out int errIndex) { errIndex = 0; if (string.IsNullOrEmpty(json) || json.Length < 2 || ((json[0] != '{' && json[json.Length - 1] != '}') && (json[0] != '[' && json[json.Length - 1] != ']'))) { return(false); } CharState cs = new CharState(); char c; for (int i = 0; i < json.Length; i++) { c = json[i]; if (SetCharState(c, ref cs) && cs.childrenStart)//设置关键符号状态。 { string item = json.Substring(i); int err; int length = GetValueLength(item, true, out err); cs.childrenStart = false; if (err > 0) { errIndex = i + err; return(false); } i = i + length - 1; } if (cs.isError) { errIndex = i; return(false); } } return(!cs.arrayStart && !cs.jsonStart); //只要不是正常关闭,则失败 }
internal static List <Dictionary <string, string> > Split(string json) { List <Dictionary <string, string> > result = new List <Dictionary <string, string> >(); if (!string.IsNullOrEmpty(json)) { Dictionary <string, string> dic = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); string key = string.Empty; StringBuilder value = new StringBuilder(); CharState cs = new CharState(); try { #region 核心逻辑 char c; for (int i = 0; i < json.Length; i++) { c = json[i]; if (!SetCharState(c, ref cs)) //设置关键符号状态。 { if (cs.jsonStart) //Json进行中。。。 { if (cs.keyStart > 0) { key += c; } else if (cs.valueStart > 0) { value.Append(c); //value += c; } } else if (!cs.arrayStart)//json结束,又不是数组,则退出。 { break; } } else if (cs.childrenStart)//正常字符,值状态下。 { string item = json.Substring(i); int temp; int length = GetValueLength(item, false, out temp); //value = item.Substring(0, length); value.Length = 0; value.Append(item.Substring(0, length)); cs.childrenStart = false; cs.valueStart = 0; //cs.state = 0; cs.setDicValue = true; i = i + length - 1; } if (cs.setDicValue)//设置键值对。 { if (!string.IsNullOrEmpty(key) && !dic.ContainsKey(key)) { //if (value != string.Empty) //{ bool isNull = json[i - 5] == ':' && json[i] != '"' && value.Length == 4 && value.ToString() == "null"; if (isNull) { value.Length = 0; } dic.Add(key, value.ToString()); //} } cs.setDicValue = false; key = string.Empty; value.Length = 0; } if (!cs.jsonStart && dic.Count > 0) { result.Add(dic); if (cs.arrayStart)//处理数组。 { dic = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); } } } #endregion } catch (Exception err) { Log.WriteLogToTxt(err); } finally { key = null; value.Length = 0; value.Capacity = 16; value = null; } } return(result); }
/// <summary> /// 设置字符状态(返回true则为关键词,返回false则当为普通字符处理) /// </summary> private static bool SetCharState(char c, ref CharState cs) { switch (c) { case '{': //[{ "[{A}]":[{"[{B}]":3,"m":"C"}]}] #region 大括号 if (cs.keyStart <= 0 && cs.valueStart <= 0) { cs.CheckIsError(c); if (cs.jsonStart && cs.state == 1) { cs.valueStart = 0; cs.childrenStart = true; } else { cs.state = 0; } cs.jsonStart = true; //开始。 return(true); } #endregion break; case '}': #region 大括号结束 if (cs.keyStart <= 0 && cs.valueStart < 2) { cs.CheckIsError(c); if (cs.jsonStart) { cs.jsonStart = false; //正常结束。 cs.valueStart = -1; cs.state = 0; cs.setDicValue = true; } return(true); } // cs.isError = !cs.jsonStart && cs.state == 0; #endregion break; case '[': #region 中括号开始 if (!cs.jsonStart) { cs.CheckIsError(c); cs.arrayStart = true; return(true); } else if (cs.jsonStart && cs.state == 1 && cs.valueStart < 2) { cs.CheckIsError(c); //cs.valueStart = 1; cs.childrenStart = true; return(true); } #endregion break; case ']': #region 中括号结束 if (!cs.jsonStart && (cs.keyStart <= 0 && cs.valueStart <= 0) || (cs.keyStart == -1 && cs.valueStart == 1)) { cs.CheckIsError(c); if (cs.arrayStart) // && !cs.childrenStart { cs.arrayStart = false; } return(true); } #endregion break; case '"': case '\'': cs.CheckIsError(c); #region 引号 if (cs.jsonStart || cs.arrayStart) { if (!cs.jsonStart && cs.arrayStart) { cs.state = 1; //如果是数组,只有取值,没有Key,所以直接跳过0 } if (cs.state == 0) //key阶段 { cs.keyStart = (cs.keyStart <= 0 ? (c == '"' ? 3 : 2) : -2); return(true); } else if (cs.state == 1) //值阶段 { if (cs.valueStart <= 0) { cs.valueStart = (c == '"' ? 3 : 2); return(true); } else if ((cs.valueStart == 2 && c == '\'') || (cs.valueStart == 3 && c == '"')) { if (!cs.escapeChar) { cs.valueStart = -2; return(true); } else { cs.escapeChar = false; } } } } #endregion break; case ':': cs.CheckIsError(c); #region 冒号 if (cs.jsonStart && cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 0) { cs.keyStart = 0; cs.state = 1; return(true); } #endregion break; case ',': cs.CheckIsError(c); #region 逗号 {"a": [11,"22", ], "Type": 2} if (cs.jsonStart && cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 1) { cs.state = 0; cs.valueStart = 0; cs.setDicValue = true; return(true); } else if (cs.arrayStart && !cs.jsonStart) //[a,b] [",",33] [{},{}] { if ((cs.state == -1 && cs.valueStart == -1) || (cs.valueStart < 2 && cs.state == 1)) { cs.valueStart = 0; return(true); } } #endregion break; case ' ': case '\r': case '\n': case '\t': if (cs.jsonStart && cs.keyStart <= 0 && cs.valueStart <= 0) { return(true); //跳过空格。 } break; default: //值开头。。 cs.CheckIsError(c); if (c == '\\') //转义符号 { if (cs.escapeChar) { cs.escapeChar = false; } else { cs.escapeChar = true; //return true; } } else { cs.escapeChar = false; } if (cs.jsonStart) { if (cs.keyStart <= 0 && cs.state <= 0) { cs.keyStart = 1; //无引号的 } else if (cs.valueStart <= 0 && cs.state == 1) { cs.valueStart = 1; //无引号的 } } else if (cs.arrayStart) { cs.state = 1; if (cs.valueStart < 1) { cs.valueStart = 1; //无引号的 } } break; } return(false); }
internal static List <T> SplitList <T>(string json, int topN, EscapeOp op) { List <T> result = new List <T>(); if (!string.IsNullOrEmpty(json)) { Type t = typeof(T); // object entity = Activator.CreateInstance(t); T entity = Activator.CreateInstance <T>(); bool hasSetValue = false; List <PropertyInfo> pInfoList = ReflectTool.GetPropertyList(t); List <FieldInfo> fInfoList = ReflectTool.GetFieldList(t); //string key = string.Empty; StringBuilder key = new StringBuilder(32); StringBuilder value = new StringBuilder(); CharState cs = new CharState(false); try { #region 核心逻辑 char c; for (int i = 0; i < json.Length; i++) { c = json[i]; if (!cs.IsKeyword(c)) //设置关键符号状态。 { if (cs.jsonStart) //Json进行中。。。 { if (cs.keyStart > 0) { key.Append(c); } else if (cs.valueStart > 0) { value.Append(c); } } else if (!cs.arrayStart)//json结束,又不是数组,则退出。 { break; } } else if (cs.childrenStart)//正常字符,值状态下。 { int temp; int length = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍 value.Length = 0; value.Append(json.Substring(i, length)); cs.childrenStart = false; cs.valueStart = 0; cs.setDicValue = true; i = i + length - 1; } if (cs.setDicValue)//设置键值对。 { if (key.Length > 0) { string k = key.ToString(); string val = value.ToString();//.TrimEnd('\r', '\n', '\t'); bool isNull = json[i - 5] == ':' && json[i] != '"' && val.Length == 4 && val == "null"; if (isNull) { val = ""; } else { val = JsonHelper.UnEscape(val, op); } object o = val; foreach (PropertyInfo p in pInfoList) { if (String.Compare(p.Name, k, StringComparison.OrdinalIgnoreCase) == 0) { if (p.CanWrite) { if (p.PropertyType.Name != "String") { o = ConvertTool.ChangeType(val, p.PropertyType); } p.SetValue(entity, o, null); hasSetValue = true; } break; } } if (!hasSetValue && fInfoList.Count > 0) { foreach (FieldInfo f in fInfoList) { if (String.Compare(f.Name, k, StringComparison.OrdinalIgnoreCase) == 0) { if (f.FieldType.Name != "String") { o = ConvertTool.ChangeType(val, f.FieldType); } f.SetValue(entity, o); hasSetValue = true; break; } } } } cs.setDicValue = false; key.Length = 0; value.Length = 0; } if (!cs.jsonStart && hasSetValue) { result.Add(entity); if (topN > 0 && result.Count >= topN) { return(result); } if (cs.arrayStart)//处理数组。 { entity = Activator.CreateInstance <T>(); hasSetValue = false; } } } #endregion } catch (Exception err) { Log.Write(err, LogType.Error); } finally { key = null; value = null; } } return(result); }
///// <summary> ///// 解析Json ///// </summary> ///// <returns></returns> //internal static List<Dictionary<string, string>> Split(string json, int topN) //{ // List<Dictionary<string, string>> result = new List<Dictionary<string, string>>(); // if (!string.IsNullOrEmpty(json)) // { // Dictionary<string, string> dic = new Dictionary<string, string>(16, StringComparer.OrdinalIgnoreCase); // int keyIndex = -1, valueIndex = -1; // int keyLength = 0, valueLength = 0; // CharState cs = new CharState(false); // try // { // #region 核心逻辑 // for (int i = 0; i < json.Length; i++) // { // char c = json[i]; // if (!cs.IsKeyword(c))//设置关键符号状态。 // { // if (cs.jsonStart)//Json进行中。。。 // { // if (cs.keyStart > 0) // { // if (keyIndex == -1) // { // keyIndex = i; // } // keyLength++; // } // else if (cs.valueStart > 0) // { // if (valueIndex == -1) // { // valueIndex = i; // } // valueLength++; // } // } // else if (!cs.arrayStart)//json结束,又不是数组,则退出。 // { // break; // } // } // else if (cs.childrenStart)//正常字符,值状态下。 // { // int temp; // valueLength = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍 // valueIndex = i; // cs.childrenStart = false; // cs.valueStart = 0; // cs.setDicValue = true; // i = i + valueLength - 1; // } // if (cs.setDicValue)//设置键值对。 // { // if (keyLength > 0) // { // string k = json.Substring(keyIndex, keyLength);// key.ToString(); // if (!dic.ContainsKey(k)) // { // string val = valueLength > 0 ? json.Substring(valueIndex, valueLength) : ""; //value.ToString(); // bool isNull = json[i - 5] == ':' && json[i] != '"' && valueLength == 4 && val == "null"; // if (isNull) // { // val = ""; // } // dic.Add(k, val); // } // } // cs.setDicValue = false; // keyIndex = valueIndex = -1; // keyLength = valueLength = 0; // } // if (!cs.jsonStart && dic.Count > 0) // { // result.Add(dic); // if (topN > 0 && result.Count >= topN) // { // return result; // } // if (cs.arrayStart)//处理数组。 // { // dic = new Dictionary<string, string>(16, StringComparer.OrdinalIgnoreCase); // } // } // } // #endregion // } // catch (Exception err) // { // Log.Write(err, LogType.Error); // } // } // return result; //} /// <summary> /// 解析Json /// </summary> /// <returns></returns> internal static List <Dictionary <string, string> > Split(string json, int topN) { List <Dictionary <string, string> > result = new List <Dictionary <string, string> >(); if (!string.IsNullOrEmpty(json)) { Dictionary <string, string> dic = new Dictionary <string, string>(16, StringComparer.OrdinalIgnoreCase); //string key = string.Empty; StringBuilder key = new StringBuilder(32); StringBuilder value = new StringBuilder(); CharState cs = new CharState(false); try { #region 核心逻辑 for (int i = 0; i < json.Length; i++) { char c = json[i]; if (!cs.IsKeyword(c)) //设置关键符号状态。 { if (cs.jsonStart) //Json进行中。。。 { if (cs.keyStart > 0) { key.Append(c); } else if (cs.valueStart > 0) { value.Append(c); } } else if (!cs.arrayStart)//json结束,又不是数组,则退出。 { break; } } else if (cs.childrenStart)//正常字符,值状态下。 { //string item = json.Substring(i); int temp; // int length = GetValueLength(false, json.Substring(i), false, out temp);//这里应该有优化的空间,传json和i,不重新生成string int length = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍 value.Length = 0; value.Append(json.Substring(i, length)); cs.childrenStart = false; cs.valueStart = 0; //cs.state = 0; cs.setDicValue = true; i = i + length - 1; } if (cs.setDicValue)//设置键值对。 { if (key.Length > 0) { string k = key.ToString(); if (!dic.ContainsKey(k)) { string val = value.ToString(); bool isNull = json[i - 5] == ':' && json[i] != '"' && value.Length == 4 && val == "null"; if (isNull) { val = ""; } dic.Add(k, val); } } cs.setDicValue = false; key.Length = 0; value.Length = 0; } if (!cs.jsonStart && dic.Count > 0) { result.Add(dic); if (topN > 0 && result.Count >= topN) { return(result); } if (cs.arrayStart)//处理数组。 { dic = new Dictionary <string, string>(16, StringComparer.OrdinalIgnoreCase); } } } #endregion } catch (Exception err) { Log.Write(err, LogType.Error); } finally { key = null; value = null; } } return(result); }