正则表达式学习:JAVA使用正则表达式递归校验JSON格式数据2

仅作为记录一下,正则校验JAVA性能效率太低。第一版在JSON个数太多时会Matcher会直接抛错STACKOVERFLOW。新改的版本循环太多会GC。
还是根据JSON源码解析的思路去进行遍历校验吧。。

 /**
     * <B>方法名称:</B>校验是否是有效JSONArray<BR>
     * <B>概要说明:</B>由于JAVA正则表达式没法递归,不能一个表达式进行匹配,只能用JAVA进行递归
     * 1.0版本使用单个正则表达式递归校验在JSON套用层数多时会引发stackoverflow异常,所以把普通字段和JSON字段分开进行校验
     * 效率依赖于JSON类型个数,无法校验全部JSON子层,根据参数大小选择一次可校验子层个数
     * 
     * 严格按照JSON官网给出的数据格式 双引号引起来的字符串 数字 JSONOBJECT JSONARRAY 波尔值和JSONNull
     * 在[]{}以及逗号前后可以有任意空字符。 <BR>
     * 
     * @param rawValue 数据
     * @return boolean 是/不是
     */
    public boolean isJSON(String rawValue) {
        try {
            JSONArray test = new JSONArray(rawValue);
            String value = rawValue;
            while (!StringUtils.isBlank(value)) {
                value = isJSONArray(rawValue);
                if ("ISNOTJSON".equals(value)) { //不是JSON
                    value = isJSONObject(rawValue);
                    if ("ISNOTJSON".equals(value)) {
                        return false;
                    } else if (StringUtils.isBlank(value)) {
                        return true;
                    }
                } else if (StringUtils.isBlank(value)) { //是JSON,被正则完全匹配
                    return true;
                }
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * <B>方法名称:</B>校验是否是有效JSONArray<BR>
     * <B>概要说明:</B>由于JAVA正则表达式没法递归,不能一个表达式进行匹配,只能用JAVA进行递归
     * 1.0版本使用单个正则表达式递归校验在JSON套用层数多时会引发stackoverflow异常,所以把普通字段和JSON字段分开进行校验
     * 效率依赖于JSON类型个数
     * 
     * 严格按照JSON官网给出的数据格式 双引号引起来的字符串 数字 JSONOBJECT JSONARRAY 波尔值和JSONNull
     * 在[]{}以及逗号前后可以有任意空字符。 <BR>
     * 
     * @param value 数据
     * @return boolean 是/不是
     */
    public String isJSONArray(String value) {
        try {
            StringBuilder arrayRegexp = new StringBuilder();
            arrayRegexp.append("^\\s*\\[\\s*");
            int capCount = 1; //捕获分组数
            for (; capCount <= 5; capCount++) {
                arrayRegexp.append(
                        "(?:(?:(?:\"[^\"]*\")|(?:true|false|null)|(?:[+-]?\\d+(?:\\.?\\d+)?(?:[eE][+-]?\\d+)?)|(?:\\s*))\\s*,\\s*)*(?:(?<json"
                                + capCount + ">(?:\\[.*?\\])|(?:\\{.*?\\})),)?");
            }
            arrayRegexp.append(
                    "(?:(?:(?:\"[^\"]*\")|(?:true|false|null)|(?:[+-]?\\d+(?:\\.?\\d+)?(?:[eE][+-]?\\d+)?)|(?:\\s*)|(?<json0>(?:\\[.*?\\])|(?:\\{.*?\\})))|");
            arrayRegexp.append("(?<json>.*?))\\]\\s*$");

            Pattern arrayPattern = Pattern.compile(arrayRegexp.toString());
            Matcher arrayMatcher = arrayPattern.matcher(value);

            if (arrayMatcher.matches()) {
                for (capCount--; capCount >= 0; capCount--) {
                    if (!StringUtils.isBlank(arrayMatcher.group("json" + capCount))
                            && !isJSON(arrayMatcher.group("json" + capCount))) {
                        return "ISNOTJSON";
                    }
                }
                return StringUtils.isBlank(arrayMatcher.group("json")) ? "" : "[" + arrayMatcher.group("json") + "]";
            }
            return "ISNOTJSON";
        } catch (Exception e) {
            e.printStackTrace();
            return "ISNOTJSON";
        }
    }

    /**
     * <B>方法名称:</B>校验是否是有效JSONArray<BR>
     * <B>概要说明:</B>由于JAVA正则表达式没法递归,不能一个表达式进行匹配,只能用JAVA进行递归
     * 1.0版本使用单个正则表达式递归校验在JSON套用层数多时会引发stackoverflow异常,所以把普通字段和JSON字段分开进行校验
     * 效率依赖于JSON类型个数
     * 
     * 严格按照JSON官网给出的数据格式 双引号引起来的字符串 数字 JSONOBJECT JSONARRAY 波尔值和JSONNull
     * 在[]{}以及逗号前后可以有任意空字符。 <BR>
     * 
     * @param value 数据
     * @return boolean 是/不是
     */
    public String isJSONObject(String value) {
        try {
            StringBuilder objectRegexp = new StringBuilder();
            objectRegexp.append("^\\s*\\{\\s*");
            int capCount = 1; //捕获分组数
            for (; capCount <= 5; capCount++) {
                objectRegexp.append(
                        "(?:\"[^\"]*\"\\s*:\\s*(?:(?:\"[^\"]*\")|(?:true|false|null)|(?:[+-]?\\d+(?:\\.?\\d+)?(?:[eE][+-]?\\d+)?))\\s*,\\s*)*(?:\"[^\"]*\"\\s*:\\s*(?<json"
                                + capCount + ">(?:\\[.*?\\])|(?:\\{.*?\\})),)?");
            }
            objectRegexp.append(
                    "(?:(?:\"[^\"]*\"\\s*:\\s*(?:(?:\"[^\"]*\")|(?:true|false|null)|(?:[+-]?\\d+(?:\\.?\\d+)?(?:[eE][+-]?\\d+)?)|(?<json0>(?:\\[.*?\\])|(?:\\{.*?\\}))))|");
            objectRegexp.append("(?<json>.*?))\\}\\s*$");

            Pattern objectPattern = Pattern.compile(objectRegexp.toString());
            Matcher objectMatcher = objectPattern.matcher(value);

            if (objectMatcher.matches()) {
                for (capCount--; capCount >= 0; capCount--) {
                    if (!StringUtils.isBlank(objectMatcher.group("json" + capCount))
                            && !isJSON(objectMatcher.group("json" + capCount))) {
                        return "ISNOTJSON";
                    }
                }
                return StringUtils.isBlank(objectMatcher.group("json")) ? "" : "{" + objectMatcher.group("json") + "}";
            }
            return "ISNOTJSON";
        } catch (Exception e) {
            e.printStackTrace();
            return "ISNOTJSON";
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_42540829/article/details/88166587