java实现一个JSON字符串处理工具,轻量级

突发奇想要造一个轮子,处理JSON字符串

特点:

1. 能够正确处理括号嵌套,但是可能会受到json中嵌套的特殊带有干扰性的单括号影响,有时间可结合第2点完善。

2. 能够正确处理带有转义引号的字符串。

3. 对json的键值对定位处理类似于新版MySQL中的处理方式“attr1.$2.subattr2”,这里$2代表找这个数组第二个

4. JSON的定义:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
完整代码如下:


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Json {
	// json的六种value
	public static final int TYPE_OBJ = 1;
	public static final int TYPE_ARR = 2;
	public static final int TYPE_STR = 3;
	public static final int TYPE_NUM = 4;
	public static final int TYPE_BOL = 5;
	public static final int TYPE_NUL = 6;
	
	// json的六种value的匹配正则
	public static final String RE_OBJ = "\\s*(\\{(.*)\\})\\s*"; // 匹配Object : {},但是嵌套会出错
	public static final String RE_ARR = "\\s*(\\[(.*?)\\])\\s*"; // 匹配数组[],但是嵌套会出错
	public static final String RE_STR = "\\s*((((?<!\\\\)\")(.*?)((?<!\\\\)\")))\\s*";// 匹配字符串,且能正确处理转义引号
	public static final String RE_NUM = "\\s*((-?(\\d+\\.)?\\d+))\\s*"; // 匹配任意数字
	public static final String RE_BOL = "\\s*(((true)|(True)|(TRUE)|T|(false)|(False)|(FALSE)|F))\\s*"; // 匹配Boolean类型
	public static final String RE_NUL = "\\s*(((NULL)|(Null)|(null)|(nul)|(NUL)|(Nul)|(NaN)))\\s*"; // 匹配空值
	
	public int type;
	public Map<String, Json> values;
	public List<Json> array;
	public String self;
	
	public Json() {
		this("{}");
	}

	public Json(String val) {
		super();
		self = val;
		if (test(RE_OBJ, val)) {
			this.type = TYPE_OBJ;
			values = new HashMap<String, Json>();
			String fk, fv;
			int rc = match(val, "{", "}");
			String content = val.substring(1, rc);
			while (content.length() > 0) {
				fk = firstVal(content);
				if (fk == null || fk.equals("{}"))
					break;
//				Log.log(content,fk);
				content = content.substring(fk.length() + 1);
				fv = firstVal(content);
				boolean next = fv.length() < content.length();
				values.put(sv(fk), new Json(fv));
				if (next) {
					content = content.substring(fv.length() + 1);
				} else {
					break;
				}
			}
		} else if (test(RE_ARR, val)) {
			this.type = TYPE_ARR;
			this.array = new ArrayList<Json>();
			int index = match(val, "[", "]");
			String str = val.substring(1, index);
			String fv;
			while (str.length() > 0) {
				fv = firstVal(str);
				boolean next = fv.length() < str.length();
				if (next) {
					str = str.substring(fv.length() + 1);
				} else {
					str = str.substring(fv.length());
				}
				array.add(new Json(fv.trim()));
			}

		} else if (test(RE_STR, val)) {
			this.type = TYPE_STR;
		} else if (test(RE_NUM, val)) {
			this.type = TYPE_NUM;
		} else if (test(RE_BOL, val)) {
			this.type = TYPE_BOL;
		} else if (test(RE_NUL, val)) {
			this.type = TYPE_NUL;
		} else {
			this.type = TYPE_STR;
			this.self = ss(val);
//			this = new Json(ss(val));
//			System.out.println("未能识别的片段:" + val);
		}
	}
	
	// 测试类型
	protected static boolean test(String REG, String str) {
		REG = "^" + REG + "$";
		boolean matches = Pattern.matches(REG, str);
//		System.out.println(matches);
		return matches;
	}
	
	// 获取正则匹配到的某个单元
	protected static String _get(String REG, String str, int which) {
		Matcher matcher = Pattern.compile(REG).matcher(str);
		String res = null;
		if (which < 1) { // 用于测试观察匹配结果
			int groupCount = matcher.groupCount();
			while (matcher.find()) {
				System.out.println("=======");
				for (int i = 0; i <= groupCount; i++) {
					res = matcher.group(i);
					 System.out.println(res);
				}
			}
		} else if (matcher.find()) {
			res = matcher.group(which).trim();
//			 System.out.println(res);
		}
		return res;
	}

	// 计数以得到左边括号的右边对应
	protected static int match(String str, String lt, String rt) {
		int r = 0;
		int i = 0;
		for (; i < str.length() - 1; i++) {
			if (str.substring(i, i + 1).equals(lt)) {
				r++;
			} else if (str.substring(i, i + 1).equals(rt)) {
				r--;
			}
			if (r == 0) {
				return i;
			}
		}
		return i;
	}
	
	// 获取最前面的一个单元的内部
	protected static String firstVal(String str) {
		String re = "null";
		if (str.substring(0, 1).equals("{")) {
			int index = match(str, "{", "}");
			re = str.substring(0, index+1);
		} else if (str.substring(0, 1).equals("[")) {
			int index = match(str, "[", "]");
			re = str.substring(0, index +1);
		} else if(test(RE_STR+".*?",str)){
			re = _get(RE_STR+".*?",str,2);
		} else if(test(RE_NUM+".*?",str)){
			re = _get(RE_NUM+".*?",str,2);
		} else if(test(RE_BOL+".*?",str)){
			re = _get(RE_BOL+".*?",str,2);
		} else if(test(RE_NUL+".*?",str)){
			re = _get(RE_NUL+".*?",str,2);
		}else {
			re = "null";
		}
		return re;
	}

	/**
	 * 返回序列化的JSON字符串
	 */
	@Override
	public String toString() {
		String str = "";
		if (this.type == TYPE_OBJ) {
			str += "{";
			for (String k : values.keySet()) {
				str += ss(k) + ":" + values.get(k) + ",";
			}
			if (str.length() > 1)
				str = str.substring(0, str.length() - 1);
			str += "}";
		} else if (this.type == TYPE_ARR) {
			str += "[";
			for (int i = 0; i < array.size() - 1; i++) {
				str += array.get(i) + ",";
			}
			if (array.size() > 0)
				str += array.get(array.size() - 1);
			str += "]";
		} else {
			str = self;
		}
		return str;
	}
	
	public static String sv(String ss) {
		return ss.substring(1, ss.length()-1);
	}
	public static String ss(String sv) {
		return "\""+sv+"\"";
	}
	public Json get(String mkey) {
		int index = mkey.indexOf('.');
		boolean inarray = mkey.startsWith("$");
		try {
			if(index>0) {
				if(inarray) return this.array.get(Integer.parseInt(mkey.substring(1,index))).get(mkey.substring(index+1));
				return this.values.get(mkey.substring(0,index)).get(mkey.substring(index+1));
			}else {
				if(inarray) return this.array.get(Integer.parseInt(mkey.substring(1,index)));
				return this.values.get(mkey);
			}
		}catch(Exception e) {
			return null;
		}
	}
	
	
	/**
	 * 写入为String
	 * @param mkey
	 * @param value
	 * @return Json
	 * 例如: json.sets("name","张三")
	 */
	public Json sets(String mkey,String value) {
		return this.set(mkey, ss(value));
	}
	
	/**
	 * 写入非String的
	 * @param mkey
	 * @param value
	 * @return Json
	 * 例如: json.sets("age",110)
	 */
	public Json setn(String mkey,int value) {
		return this.set(mkey, String.valueOf(value));
	}
	/**
	 * 不推荐使用
	 * @param mkey
	 * @param value
	 * @return
	 * 例如: json.sets("name","\"张三\"")
	 */
	public Json set(String mkey,String value) {
		int index = mkey.indexOf('.');
		boolean inarray = mkey.startsWith("$");
		if(index>0) {
			if(inarray) {
				this.array.get(Integer.parseInt(mkey.substring(1,index))).set(mkey.substring(index+1),value);
			}
			else {
				this.values.get(mkey.substring(0,index)).set(mkey.substring(index+1),value);
			}
		}else {
			Json json = new Json(value);
			if(inarray) {
				int idx = Integer.parseInt(mkey.substring(1));
				if(this.array==null) this.array = new ArrayList<Json>();
				if(this.array.size()<idx+1) {
					while (this.array.size()<idx+1) {
						this.array.add(new Json(""));
					}
				}
//				System.out.println(this);
				this.array.set(idx,json);
			}
			else {
				this.values.put(mkey,json);
			}
		}
		return this;
	}
	
	/**
	 * 去除最外层的引号
	 * @return
	 */
	public String val() {
		return sv(self);
	}
	
	// TODO 迭代器,用于对{} 和 []的遍历
	public void next(String key) {
		
	}
	
	// TODO 获得 {}key的个数或者[]的个数
	public void length(String mKey) {
		
	}

	// 测试
	public static void main(String[] args) {
//		String val = firstVal("NaNFlase19.80\"12\":\"43\"");
//		System.out.println(val);
//		String demo = "{\"name\":\"tim\",\"age\":24,\"rate\":0.9,\"active\":-0.83,\"major\":[{\"name\":\"数字\",\"score\":100},{\"name\":\"ds\",\"score\":{\"r1\":\"10\",\"r2\":100}}],\"test\":\"[\\\"name\\\",false,[],{\\\"1\\\":\\\"2\\\",\\\"3\\\":\\\"sanjin\\\"},[\\\"name\\\",false,[],{\\\"1\\\":\\\"2\\\",\\\"3\\\":\\\"sanjin\\\"},[]]]\",\"dic\":{}}";
//		Json json = new Json(demo);
//		System.out.println(json);
//		System.out.println(json.get("major.$1.name"));
//		System.out.println(json.set("major.$1.name","大佬"));
//		System.out.println(json.set("test","[]"));
//		Json json = new Json();
//		json.set("cmd", "onlineList_OK");
//		json.set("list", "[]");
//		json.set("list.$0","123");
//		System.out.print(json);
		System.out.println(new Json("{\"clientId\":\"123456\",\"x\":11,\"y\":0,\"step\":0,\"cmd\":\"step\",\"ememyId\":\"13456\",\"isMyWhite\":false} ").get("ememyId"));
	}
}

上述代码运行效果如:

{"major":[{"name":"数字"},{"name":"ds"}],"test":"[\"name\",false,[],{\"1\":\"2\",\"3\":\"sanjin\"},[\"name\",false,[],{\"1\":\"2\",\"3\":\"sanjin\"},[]]]","rate":0.9,"name":"tim","active":-0.83,"age":24}
"ds"
{"major":[{"name":"数字"},{"name":"大佬"}],"test":"[\"name\",false,[],{\"1\":\"2\",\"3\":\"sanjin\"},[\"name\",false,[],{\"1\":\"2\",\"3\":\"sanjin\"},[]]]","rate":0.9,"name":"tim","active":-0.83,"age":24}
{"major":[{"name":"数字"},{"name":"大佬"}],"test":[],"rate":0.9,"name":"tim","active":-0.83,"age":24}

有待实现

  1. 遍历
  2. 反序列化为java对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值