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對象
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章