字符串处理--->逻辑表达式转可执行脚本字符串
/** * 执行函数脚本 * * @since author: l00050286 date: 2023/4/10 15:26 * @param scriptStr 函数脚本字符串 * @param functionName 函数名 * @return java.lang.Object */ public static Object executeFunctionScript(String scriptStr,String functionName) throws Exception { ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); engine.eval(scriptStr); Invocable jsInvoke = (Invocable) engine; return jsInvoke.invokeFunction(functionName); } /** * 获取可执行函数Str * * @since author: l00050286 date: 2023/4/10 14:46 * @param sourceFormula 计算规则 * @param endSign 计算规则结束标识 * @param functionName 可执行函数名称 * @param factorValueMap 计算规则计算因子的值 * @return java.lang.String */ public static String getScriptStr(String sourceFormula, String endSign, String functionName, Map<String, String> factorValueMap) { int length = endSign.length(); String column = StringUtils.trimAllWhitespace(sourceFormula); String splitStr = "IF|THEN|OTHERWISE|AND|OR|>=|<=|>|<|==|\\+|-|\\*|/|\\?|:"; if (column.indexOf("IF") == 0) { String logicScript = column.substring(0, column.length() - length); // 去掉结束标记 Map<String, String> factorMap = new HashMap<>(); // 1、设置需要替换的最小计算因数 setFactorMap(factorMap, logicScript, splitStr); // 2、格式化逻辑脚本 splitStr = "IF|THEN|OTHERWISE|AND|OR|>=|<=|>|<|==|\\+|-|\\*|/|\\;|\\?|:|" + endSign; String formatFormula = CommonUtil.formatLogicFormula(column, endSign, splitStr); // 3、格式化逻辑脚本转换成可执行函数 return scriptTransferFunction(formatFormula, factorMap, functionName, endSign, factorValueMap); } else { Map<String, String> factorMap = new HashMap<>(); // 1、设置需要替换的最小计算因数 setFactorMap(factorMap, column, splitStr); // 2、格式化逻辑脚本 splitStr = "IF|THEN|OTHERWISE|AND|OR|>=|<=|>|<|==|\\+|-|\\*|/|\\;|\\?|:|" + endSign; String formatFormula = CommonUtil.formatLogicFormula(column, endSign, splitStr); // 3、格式化逻辑脚本转换成可执行函数 return scriptTransferFunction(formatFormula, factorMap, functionName, endSign, factorValueMap); } } /** * 设置需要替换的最小计算因数 * * @since author: l00050286 date: 2023/4/10 14:40 * @param factorMap 保存需要替换的最小计算因数Map * @param logicScript 逻辑脚本 * @param splitStr 分隔符 * @return void */ public static void setFactorMap(Map<String,String> factorMap,String logicScript,String splitStr){ String[] elementArray = logicScript.split(";"); int serialIndex=0; // 解析公式获取需要替换的最小计算因数 for (String tempElement : elementArray) { String[] split = tempElement.split(splitStr); for (String minCalculationFactor : split) { if(!CommonUtil.isEmpty(minCalculationFactor)){ int j = minCalculationFactor.indexOf("["); int k = minCalculationFactor.indexOf("]"); if (j > -1 && k > -1) { // 考虑到 ( ) 的情况 int l = minCalculationFactor.indexOf(")"); String element = (l > -1 ? minCalculationFactor.substring(j, l) : minCalculationFactor.substring(j)); if(factorMap.get(element) == null) { serialIndex++; factorMap.put(element, "param" + serialIndex); // 考虑到存在()的情况 int m = minCalculationFactor.indexOf("("); if (m > -1 || l > -1) { factorMap.put(minCalculationFactor, element); } }else{ // 考虑到(,((,(((...和),)),)))...的情况 if(factorMap.get(minCalculationFactor) == null){ factorMap.put(minCalculationFactor, element); } } } } } } } /** * 格式化逻辑公式 * * @since author: l00050286 date: 2023/3/31 18:28 * @param column 计算规则公式 * @param endSign 原始字符串结束标识 * @param splitStr 分隔字符串 * "IF|THEN|OTHERWISE|AND|OR|>=|<=|>|<|==|\\+|-|\\*|/|\\;|" * "IF|THEN|OTHERWISE|AND|OR|>=|<=|>|<|==|\\+|-|\\*|/" * @return java.lang.String */ public static String formatLogicFormula(String column,String endSign,String splitStr) { List<String> separatorList = new ArrayList<>(); String[] split1 = column.split(splitStr); int i = 0; int j = 1; int length = split1.length; while (column.length() > 0 && i < length && j < length) { column = column.substring(split1[i].length()); int i1 = column.indexOf(split1[j]); separatorList.add(column.substring(0, i1)); column = column.substring(i1); i++; j++; } StringBuilder stringBuilder = new StringBuilder(); int size = separatorList.size(); for (int i1 = 0; i1 < length; i1++) { if(!CommonUtil.isEmpty(split1[i1])){ stringBuilder.append(split1[i1]).append(" "); } if (i1 < size) { String tmp = separatorList.get(i1); if(tmp.length()>1 && tmp.indexOf(";")==0){ stringBuilder.append(";").append(" ").append(tmp.substring(1)).append(" "); }else{ stringBuilder.append(separatorList.get(i1)).append(" "); } } } stringBuilder.append(endSign); return stringBuilder.toString(); } /** * 格式化逻辑脚本转换成可执行函数 * * @since author: l00050286 date: 2023/4/10 15:05 * @param formatFormula 格式化逻辑脚本 * @param factorMap 需要替换的最小计算因数Map * @param functionName 可执行函数名称 * @param endSign 格式化逻辑脚本结束标识 * @return java.lang.String */ public static String scriptTransferFunction(String formatFormula, Map<String, String> factorMap, String functionName, String endSign, Map<String, String> factorValueMap) { String[] elementAllArray = formatFormula.split(" "); StringBuilder stringBuilderFormula = new StringBuilder(); factorMap.forEach((key, value) -> { if (key.indexOf("(") == -1 && key.indexOf(")") == -1) { if (factorValueMap.get(key) == null) { stringBuilderFormula.append("var ").append(value).append(" = 10;\n"); } else { stringBuilderFormula.append("var ").append(value).append(" = ").append(factorValueMap.get(key)).append(";\n"); } } }); stringBuilderFormula.append("function "); if (formatFormula.indexOf("IF") == 0) { stringBuilderFormula.append(functionName).append("(){\n var result = 0;\n"); } else { stringBuilderFormula.append(functionName).append("(){\n var result = ( \n"); } for (String element : elementAllArray) { switch (element) { case "IF": stringBuilderFormula.append(" if ("); break; case "THEN": stringBuilderFormula.append(") {\n\t result = "); break; case "AND": stringBuilderFormula.append(" && "); break; case "OR": stringBuilderFormula.append(" || "); break; case "OTHERWISE": stringBuilderFormula.append(";\n } else {\n\t result = "); break; case ";": stringBuilderFormula.append(";\n } else"); break; default: if (factorMap.get(element) == null) { if (element.equals(endSign)) { if(formatFormula.indexOf("IF") == 0){ stringBuilderFormula.append(";\n }\n return result ;\n}"); } else{ stringBuilderFormula.append(" );\n return result ;\n}"); } } else { stringBuilderFormula.append(" ").append(element); } } else { String factor = factorMap.get(element); String parameter = factorMap.get(factor); if (parameter != null) { element = element.replace(factor, parameter); stringBuilderFormula.append(element); } else { stringBuilderFormula.append(" ").append(factorMap.get(element)); } } break; } } return stringBuilderFormula.toString(); }