由于业务的扩张,我选择让数据人员写伪json来处理 计算数据大表到小表excel映射,现使用伪json配置映射关系。
主要担心数据人员少写引号以及配置效率等问题。代码如下注释写的很清楚了.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
namespace TestJson
{
class Program
{
static void Main(string[] args)
{
string jsonStr = "{name:计算数据大表名称,sheet:[{sheetName:不同时期,special:[准业务,磨合期,老业主,稳定期]},{sheetName:50分制}]}";
string jsonStr2 = "{\"name\":\"计算数据大表名称\",\"sheet\":[{\"sheetName\":\"不同时期\",\"special\":[\"准业务\",\"磨合期\",\"老业主\",\"稳定期\"]},{\"sheetName\":\"50分制\"}]}";
jsonStr = jsonStr.Replace(",", ",");
string res = ConvertJsonStr(jsonStr);
Console.WriteLine(res);
JObject.Parse(res);
Console.Read();
}
static string ConvertJsonStr(string jsonStr)
{
string temp = jsonStr;
string[] tempStrs;
//如果是json数据个格式
if (jsonStr[0].ToString() == "{")
{
List<string> resList = new List<string>();
jsonStr = RemoveHeadEnd(jsonStr);
tempStrs = GetOuterList(jsonStr,',');
for (int i = 0; i < tempStrs.Length; i++)
{
string tempStr = tempStrs[i];
string[] strs = GetOuterList(tempStr, ':');
//将json的key加上引号
strs[0] = "\"" + strs[0] + "\"";
//递归处理json的value 因为json的value可能是json array或者普通字符串
strs[1] = ConvertJsonStr(strs[1]);
tempStr = string.Join(":", strs);
resList.Add(tempStr);
}
return "{" + string.Join(",", resList) + "}";
}
//处理是array的情况
else if (jsonStr[0].ToString() == "[")
{
List<string> resList = new List<string>();
jsonStr = RemoveHeadEnd(jsonStr);
tempStrs = GetOuterList(jsonStr,',');
for (int i = 0; i < tempStrs.Length; i++)
{
string tempStr = tempStrs[i];
//array的每一项都有可能是json array 普通值直接递归
tempStr = ConvertJsonStr(tempStr);
resList.Add(tempStr);
}
return "[" + string.Join(",", resList) + "]";
}
//处理是普通字符的情况
else
{
return "\"" + jsonStr + "\"";
}
}
static string RemoveHeadEnd(string str)
{
str = str.Remove(0, 1);
str = str.Remove(str.Length - 1, 1);
return str;
}
static string[] GetOuterList(string jsonStr,char fuhao)
{
int index = 0;
int lastIndex =0;
List<string> res = new List<string>();
while (true)
{
int finalIndex = jsonStr.IndexOf(fuhao, lastIndex);
//后面已经没有逗号了取到末尾
if (finalIndex<0)
{
finalIndex = jsonStr.Length;
}
string data = jsonStr.Substring(index, finalIndex - index);
if (IsBanlance(data))
{
res.Add(data);
index = finalIndex + 1;
}
if (finalIndex == jsonStr.Length)
{
break;
}
lastIndex = finalIndex + 1;
}
return res.ToArray();
}
//json规则只有逗号一个逗号左右2边的[{和]}是平衡的才是个外围json
static bool IsBanlance(string str)
{
int leftSmall = 0;
int leftBig = 0;
int rightSmall = 0;
int rightBig = 0;
for (int i = 0; i < str.Length; i++)
{
char ch = str[i];
switch (ch)
{
case '[': leftSmall++; break;
case ']': rightSmall++; break;
case '{': leftBig++; break;
case '}': rightBig++; break;
default:
break;
}
}
if (leftSmall == rightSmall && leftBig == rightBig)
{
return true;
}
return false;
}
}
}
这里主要运用到了递归加banlance判断
运行效果如图: