· 基本介绍
现在需求是想实现一种既支持算术运算又支持逻辑运算的表达式,网上找了好多资料,大多都是以下情况:
-> 基于栈或队列来实现基本的算术运算
-> 基于模板引擎(js、Nashorn、javascript等)
· 存在问题
-> 底层JS引擎计算时会默认把 true 转化为1 ,false转化为0 (解决: 分支思想)
-> 对于&&、|| 结尾的字符串表达式并不报错,其会直接删除, 判断为合理(解决: 添加校验逻辑)
· 实现思路
· 实现过程
1、 使用前提: Java项目中引入依赖 jep 如下所示
2、基于JS引擎拆解执行逻辑(思想: 采用归并思想)
import com.monitor.common.exception.ServiceException;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Yaojinge
* @Description : 表达式计算工具类
* @date 2024/8/31
*/
public class ExpressionUtil {
/**
* 逻辑运算符 ||
*/
static final String EXPRESSION_OR="||";
/**
* 逻辑运算符 &&
*/
static final String EXPRESSION_AND="&&";
/**
* 逻辑运算符 &
*/
static final String EXPRESSION_SINGLE_AND="&";
/**
* 逻辑运算符 |
*/
static final String EXPRESSION_SINGLE_OR="|";
/**
* 正则匹配 ||
*/
static final String REGULAR_MATCH_OR="\\|\\|";
/**
* 正则表达式匹配中文字符串
*/
static final String PATTERN_CHINESE = "[\\u4e00-\\u9fa5]+";
/**
* 正表达式,匹配单独的 = ,而非 ===、==
*/
static final String PATTERN_EQUAL = "\\b=\\b";
/**
* 错误符号组合列表
*/
static final String[] COMBINE_LIST = {"*true", "true*", "/true", "true/", "+true", "true+", "-true", "true-",
"/true", "true/", "%true", "%false", "false%", "true%", "*false", "false*", "/false", "false/", "+false", "false+", "-false", "false-",
">true", "<true", ">false", "<false", ">=true", "<=true", ">=false", "<=false"};
/**
* 暂不支持符号列表
*/
final static String[] SYMBOL_LIST = {"++","--", ">>","<<", ">>>", "^", "[", "]", "{", "}", "?:", "instanceof", "+=", "-=", "*=",
"/=", "%=", ">>=", "<<=", ">>>=", "&=", "|=", "^=", "&&=", "||=", "?:"};
/**
* 非法字符列表(待完善)
*/
final static String[] ILLEGAL_LIST = {"@", "#", "$", "~", "null"};
/**
* 布尔运算符集合
*/
final static Set<String> BOOLEAN_SET = new HashSet<>(Arrays.asList("true", "false"));
/**
* 表达式校验和计算
* @param expression 表达式
* @return 计算结果
*/
public static Object calculateExpression(String expression) {
// 非空校验
if (expression == null || expression.length() == 0) {
throw new ServiceException("表达式不能为空!");
}
// 去除空字符
expression = expression.replace(" ", "");
// 排除暂不支持的运算符
checkSymbols(expression);
// 排除非法运算符组合
checkLegality(expression);
// 创建JS引擎
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
// 统计左右括号个数
char[] array = expression.toCharArray();
int leftCount = 0,rightCount=0;
for (char c : array) {
if (c == '(') {
leftCount++;
} else if (c == ')') {
rightCount++;
}
}
// 根据左右括号的个数执行对应的逻辑
return getResult(expression, engine, leftCount, rightCount);
}
/**
* 根据左右括号的个数执行对应的计算逻辑
* @param expression 表达式
* @param engine JS引擎
* @param leftCount 左括号个数
* @param rightCount 右括号个数
* @return 计算结果
*/
private static Object getResult(String expression, ScriptEngine engine, int leftCount, int rightCount) {
Object result = null;
if (leftCount == 0 && rightCount == 0) {
result = attainOutcome(expression, engine);
} else if (leftCount != rightCount) {
throw new ServiceException("表达式左右括号数量不匹配!");
} else {
boolean flag = false;
char[] charArray = expression.toCharArray();
for (int i = 0; i < leftCount; i++) {
int leftIndex = 0,rightIndex = 0;
// 左括号找最右侧的位置
for (int j = 0; j < charArray.length; j++) {
if (charArray[j] == '(') {
leftIndex = j;
}
}
// 根据左括号位置找离其最近的右括号位置
for (int j = leftIndex; j < charArray.length; j++) {
if (charArray[j] == ')') {
rightIndex = j;
break;
}
}
// 取出括号中算式进行计算
if (rightIndex != 0 && (rightIndex > leftIndex)) {
// 拼接字符串
String leftString = expression.substring(0, leftIndex);
String middleString = expression.substring(leftIndex + 1, rightIndex);
String rightString = expression.substring(rightIndex + 1);
// 判断是否还需要再次通过JS引擎计算
boolean condition = (leftString.length() > 0 || rightString.length() > 0);
if ((i == leftCount - 1) || condition) {
// 若是还有其他算式,再执行一次计算逻辑
flag = true;
}
// 将中间的字符串放入到JS中进行计算
result = attainOutcome(middleString, engine);
// 执行完成后,拼接结果,并校验合法性
expression = leftString + result.toString() + rightString;
checkLegality(expression);
// 校验通过将表达式切分成字符数组
charArray= expression.toCharArray();
} else if ((leftIndex > rightIndex)) {
throw new ServiceException("表达式括号位置顺序错误!");
}
}
if (flag) {
// 将最后一次的计算也放入到情况一中执行
result = attainOutcome(expression, engine);
}
}
return result;
}
/**
* 检验表达式中是否存在暂不支持的字符
*
* @param expression 表达式
*/
private static void checkSymbols(String expression) {
for (String s : SYMBOL_LIST) {
if (expression.contains(s)) {
throw new ServiceException("暂不支持该表达式中的<" + s + ">字符运算");
}
}
}
/**
* 过滤非法字符
*
* @param expression 表达式
*/
private static void filterIllegalSymbols(String expression) {
for (String item : ILLEGAL_LIST) {
if (expression.contains(item)) {
throw new ServiceException("表达式中存在非法字符<" + item + ">,请检查");
}
}
}
/**
* 校验表达式合法性
* @param expression 表达式
*/
private static void checkLegality(String expression) {
// 过滤运算符 | & =
if (expression.matches(PATTERN_EQUAL)) {
throw new ServiceException("底层引擎不支持=运算,请修改");
} else if (containsChinese(expression)) {
throw new ServiceException("表达式中存在中文字符,请修改");
}
// 非法字符过滤
filterIllegalSymbols(expression);
// 表达式前后缀过滤(&&、||)
boolean condition = expression.startsWith(EXPRESSION_OR) || expression.endsWith(EXPRESSION_OR);
boolean condition1 = expression.startsWith(EXPRESSION_AND) || expression.endsWith(EXPRESSION_AND);
if (condition1 || condition) {
throw new ServiceException("表达式前后缀不符合运算规则,请检查");
}
// 错误组合过滤
for (String s : COMBINE_LIST) {
if (expression.contains(s)) {
throw new ServiceException("<" + s + ">不符合运算规则,请检查");
}
}
}
/**
* 获取计算结果
* @param expression 表达式
* @param engine JS引擎
* @return 操作结果
*/
private static Object attainOutcome(String expression, ScriptEngine engine) {
Object result = null;
// 剪枝处理(表达式以||或&&开头或结尾)
boolean condition = expression.startsWith(EXPRESSION_OR) || expression.endsWith(EXPRESSION_OR);
boolean condition1 = expression.startsWith(EXPRESSION_AND) || expression.endsWith(EXPRESSION_AND);
if (condition1 || condition) {
throw new ServiceException("表达式中&&或||两侧存在空值,请检查");
}
// 判断字符串中是否含有 || 符
if (expression.contains(EXPRESSION_OR)) {
try {
// 根据||符号进行拆分成字符串数组
String[] strList = expression.split(REGULAR_MATCH_OR);
for (int i = 0; i < strList.length; i++) {
// 遍历每个字符数组
if (strList[i].contains(EXPRESSION_AND)) {
// 存在&&符号
String[] list = strList[i].split(EXPRESSION_AND);
int amount = list.length;
if (amount > 0) {
int count = calculateAndCollect(engine, list);
//条件过滤及拼接
if (count != 0 && count == amount) {
int total = 0;
StringBuilder sb = new StringBuilder();
for (int j = 0; j < list.length; j++, total++) {
if (BOOLEAN_SET.contains(list[j].trim()) && (j != list.length - 1)) {
sb.append(list[j]).append(EXPRESSION_AND);
} else if (BOOLEAN_SET.contains(list[j].trim()) && j == list.length - 1) {
sb.append(list[j]);
} else {
throw new ServiceException(EXPRESSION_AND + "运算符两侧存在非布尔值,表达式错误,请检查");
}
}
if (total != 0 && total == amount) {
try {
strList[i] = engine.eval(sb.toString()).toString();
} catch (ScriptException e) {
throw new ServiceException("表达式有误,请检查");
}
}
}
}
} else {
if(strList[i].contains(EXPRESSION_SINGLE_OR)||strList[i].contains(EXPRESSION_SINGLE_AND)){
throw new ServiceException("表达式不支持|或&运算,请检查");
}
strList[i] = engine.eval(strList[i]).toString();
}
}
StringBuilder sb = new StringBuilder();
// 拼接字符串
for (int i = 0; i < strList.length; i++) {
if (i != strList.length - 1 && (BOOLEAN_SET.contains(strList[i].trim()))) {
sb.append(strList[i]).append(EXPRESSION_OR);
} else if (i == strList.length - 1 && (BOOLEAN_SET.contains(strList[i].trim()))) {
sb.append(strList[i]);
} else {
throw new ServiceException(EXPRESSION_OR + "运算符两侧因数存在非布尔值,表达式错误,请检查");
}
}
// 执行计算逻辑
result = engine.eval(sb.toString());
} catch (ScriptException e) {
throw new ServiceException("表达式有误,请检查");
}
} else if (expression.contains(EXPRESSION_AND)) {
// 存在&&符号
String[] list = expression.split(EXPRESSION_AND);
int amount = list.length;
if (amount > 0) {
int count = calculateAndCollect(engine, list);
// 字符串数组拼接和计算
if (count != 0 && count == amount) {
int total = 0;
StringBuilder sb = new StringBuilder();
for (int j = 0; j < list.length; j++, total++) {
if (BOOLEAN_SET.contains(list[j].trim()) && j != list.length - 1) {
// 开始进行拼接
sb.append(list[j]).append(EXPRESSION_AND);
} else if (BOOLEAN_SET.contains(list[j].trim()) && j == list.length - 1) {
// 最后一个,直接拼接即可
sb.append(list[j]);
} else {
throw new ServiceException(EXPRESSION_AND + "运算符两侧存在非布尔值,表达式错误,请检查");
}
}
if (total != 0 && total == amount) {
try {
result = engine.eval(sb.toString());
} catch (ScriptException e) {
e.printStackTrace();
}
}
}
}
} else {
// 情况三: 表达式中不存在 (、)、||、&& 等运算符,直接通过JS引擎计算即可
if (expression.contains(EXPRESSION_SINGLE_OR)||expression.contains(EXPRESSION_SINGLE_AND)){
throw new ServiceException("表达式不支持|或&运算,请检查");
}
try {
result = engine.eval(expression);
} catch (ScriptException e) {
throw new RuntimeException("表达式有误,请检查!");
}
}
return result;
}
/**
* 计算集合中的每个元素位置表达式
* @param engine JS引擎
* @param list 表达式集合
* @return 计数器结果
*/
private static int calculateAndCollect(ScriptEngine engine, String[] list) {
int count = 0;
// 遍历每个字符数组进行单独计算
for (int j = 0; j < list.length; j++) {
// 空值校验
if (list[j] == null || "".equals(list[j])) {
throw new ServiceException("表达式运算符" + EXPRESSION_AND + "两侧存在空值,请检查");
}
if (BOOLEAN_SET.contains(list[j].trim())) {
count++;
} else {
if(list[j].contains("|")||list[j].contains("&")){
throw new ServiceException("表达式不支持|或&运算,请检查");
}
try {
// 单独计算并赋值
list[j] = engine.eval(list[j]).toString();
count++;
} catch (ScriptException e) {
throw new ServiceException("表达式有误,请检查");
}
}
}
return count;
}
/**
* 判断字符串是否包含中文
* @param str 字符串
* @return 包含中文返回true
*/
public static boolean containsChinese(String str) {
Pattern pattern = Pattern.compile(PATTERN_CHINESE);
Matcher matcher = pattern.matcher(str);
return matcher.find();
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
- 245.
- 246.
- 247.
- 248.
- 249.
- 250.
- 251.
- 252.
- 253.
- 254.
- 255.
- 256.
- 257.
- 258.
- 259.
- 260.
- 261.
- 262.
- 263.
- 264.
- 265.
- 266.
- 267.
- 268.
- 269.
- 270.
- 271.
- 272.
- 273.
- 274.
- 275.
- 276.
- 277.
- 278.
- 279.
- 280.
- 281.
- 282.
- 283.
- 284.
- 285.
- 286.
- 287.
- 288.
- 289.
- 290.
- 291.
- 292.
- 293.
- 294.
- 295.
- 296.
- 297.
- 298.
- 299.
- 300.
- 301.
- 302.
- 303.
- 304.
- 305.
- 306.
- 307.
- 308.
- 309.
- 310.
- 311.
- 312.
- 313.
- 314.
- 315.
- 316.
- 317.
- 318.
- 319.
- 320.
- 321.
- 322.
- 323.
- 324.
- 325.
- 326.
- 327.
- 328.
- 329.
- 330.
- 331.
- 332.
- 333.
- 334.
- 335.
- 336.
- 337.
- 338.
- 339.
- 340.
- 341.
- 342.
- 343.
- 344.
- 345.
- 346.
- 347.
- 348.
- 349.
- 350.
- 351.
- 352.
- 353.
- 354.
- 355.
- 356.
- 357.
- 358.
- 359.
- 360.
- 361.
- 362.
- 363.
- 364.
- 365.
- 366.
- 367.
- 368.
- 369.
- 370.
- 371.
- 372.
- 373.
- 374.
- 375.
测试代码:
/**
* @author Yaojinge
* @Description
* @date 2024/8/31
*/
public class IllegalExpressionTest {
// 日志对象
private static final Logger logger = LoggerFactory.getLogger(LegalExpressionTest.class);
public static void main(String[] args) {
System.out.println("---------------------------------------------------------------------------非法运算测试--------------------------------------------------");
// 左右括号位置顺序错误
logger.info("=> )1+2( = {}", ExpressionUtil.calculateExpression(")1+2(").toString());
// 表达式左右括号数量不匹配
logger.info("=> )1+2 = {}", ExpressionUtil.calculateExpression(")1+2").toString( ));
// 布尔值运算不符合规则
logger.info("=> (1>2)+10 = {}", ExpressionUtil.calculateExpression("(1>2)+10").toString());
// 表达式前后缀不符合运算规则,请检查
logger.info("=> || (7>2) = {}", ExpressionUtil.calculateExpression("|| (7>2)").toString());
logger.info("=> (7>2) || = {}", ExpressionUtil.calculateExpression("(7>2) ||").toString());
logger.info("=> (7>2) && = {}", ExpressionUtil.calculateExpression("(7>2) &&").toString());
logger.info("=> &&(7>2) = {}", ExpressionUtil.calculateExpression("&&(7>2)").toString());
logger.info("=> ((7>2)&&(8>2))&& = {}", ExpressionUtil.calculateExpression("((7>2)&&(8>2))&&").toString());
// 表达式中&&或||两侧存在空值,请检查(运算表达式直接以 && 或 || 开头或结尾)
logger.info("=> ((7>2)&&)&&(8>2) = {}", ExpressionUtil.calculateExpression("((7>2)&&)&&(8>2)").toString());
logger.info("=> ((7>2)||)&&(8>2) = {}", ExpressionUtil.calculateExpression("((7>2)||)&&(8>2)").toString());
// 表达式中存在非法字符组合
logger.info("=> (1<2)*3 = {}", ExpressionUtil.calculateExpression("(1<2)*3").toString());
logger.info("=> (1<2)+3 = {}", ExpressionUtil.calculateExpression("(1<2)+3").toString());
logger.info("=> (1<2)-3 = {}", ExpressionUtil.calculateExpression("(1<2)-2").toString());
logger.info("=> (1<2)/3 = {}", ExpressionUtil.calculateExpression("(1<2)/3").toString());
logger.info("=> (1<2)%3 = {}", ExpressionUtil.calculateExpression("(1<2)<3").toString());
// 表达式中存在中文字符,请修改
logger.info("=> (1<2中文)<3 = {}", ExpressionUtil.calculateExpression("(1<2中文)<3").toString());
// 表达式不支持|或&运算,请检查
logger.info("=> (1|2)||3 = {}", ExpressionUtil.calculateExpression("(1|2)||3").toString());
logger.info("=> (1&2)&&3 = {}", ExpressionUtil.calculateExpression("(1&2)&&3").toString());
// 表达式中存在非法字符<#>,请检查
logger.info("=> (1<2)#3 = {}", ExpressionUtil.calculateExpression("(1<2)#3"));
logger.info("=> (1<2)@3 = {}", ExpressionUtil.calculateExpression("(1<2)@3"));
logger.info("=> (1<2)$3 = {}", ExpressionUtil.calculateExpression("(1<2)$3"));
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
/**
* @author Yaojinge
* @Description
* @date 2024/8/30
*/
public class LegalExpressionTest {
/**
* 日志对象
*/
private static final Logger logger = LoggerFactory.getLogger(LegalExpressionTest.class);
public static void main(String[] args) {
//算术运算
System.out.println("-------------------------------------------------------------------------算术运算-------------------------------------------------------------------");
logger.info("=> 1+2 = {}", ExpressionUtil.calculateExpression("1+2").toString());
logger.info("=> 1-2 = {}", ExpressionUtil.calculateExpression("1-2").toString());
logger.info("=> 1*2 = {}", ExpressionUtil.calculateExpression("1*2").toString());
logger.info("=> 1/2 = {}", ExpressionUtil.calculateExpression("1/2").toString());
logger.info("=> 1%2 = {}", ExpressionUtil.calculateExpression("1%2").toString());
// 复杂算术运算
System.out.println("-------------------------------------------------------------------------复杂算术运算------------------------------------------------------------------");
logger.info("=> 1+2*3 = {}", ExpressionUtil.calculateExpression("1+2*3").toString());
logger.info("=> 1+2*3/4 = {}", ExpressionUtil.calculateExpression("1+2*3/4").toString());
logger.info("=> 1+2*(3/4) = {}", ExpressionUtil.calculateExpression("1+2*(3/4)").toString());
logger.info("=> 1+2*(3/4)*5 = {}", ExpressionUtil.calculateExpression("1+2*(3/4)*5").toString());
logger.info("=> 1+2*(3/4)*5%6 = {}", ExpressionUtil.calculateExpression("1+2*(3/4)*5%6").toString());
logger.info("=> 1+2*(3/4)*5%6+7-8/9*10%11 = {}", ExpressionUtil.calculateExpression("1+2*(3/4)*5%6+7-8/9*10%11").toString());
logger.info("=> (32+21)%100 ={}", ExpressionUtil.calculateExpression("(32+21)%100").toString());
logger.info("=> 4.2-(32+21)%100 = {}", ExpressionUtil.calculateExpression("4.2-(32+21)%100").toString());
logger.info("=> (32+21)/100 = {}", ExpressionUtil.calculateExpression("(32+21)/100").toString());
logger.info("=> 4.1+(32+21)/100 = {}", ExpressionUtil.calculateExpression("4.1+(32+21)/100").toString());
//关系运算
System.out.println("--------------------------------------------------------------------------关系运算------------------------------------------------------------------");
logger.info("=> 1>2 = {}", ExpressionUtil.calculateExpression("1>2").toString());
logger.info("=> 1<2 = {}", ExpressionUtil.calculateExpression("1<2").toString());
logger.info("=> 1>=2 = {}", ExpressionUtil.calculateExpression("1>=2").toString());
logger.info("=> 1<=2 = {}", ExpressionUtil.calculateExpression("1<=2").toString());
logger.info("=> 1==2 = {}", ExpressionUtil.calculateExpression("1==2").toString());
logger.info("=> 1===2 = {}", ExpressionUtil.calculateExpression("1===2").toString());
logger.info("=> 1!=2 = {}", ExpressionUtil.calculateExpression("1!=2").toString());
logger.info("=> 1!==2 = {}", ExpressionUtil.calculateExpression("1!==2").toString());
// 复杂关系运算
System.out.println("---------------------------------------------------------------------------复杂关系运算------------------------------------------------------------------");
logger.info("=> 1>2&&2>3 = {}", ExpressionUtil.calculateExpression("1>2&&2>3").toString());
logger.info("=> 1>2&&2<3 = {}", ExpressionUtil.calculateExpression("1>2&&2<3").toString());
logger.info("=> 1>2||2<3 = {}", ExpressionUtil.calculateExpression("1>2||2<3").toString());
logger.info("=> (1>2||2<3)&&3>4 = {}", ExpressionUtil.calculateExpression("(1>2||2<3)&&3>4").toString());
logger.info("=> (1>2||2<3)&&3<4 = {}", ExpressionUtil.calculateExpression("(1>2||2<3)&&3<4").toString());
logger.info("=> (1>2||2<3)&&(3>4||4<5) = {}", ExpressionUtil.calculateExpression("(1>2||2<3)&&(3>4||4<5)").toString());
logger.info("=> (1>2||2<3)&&(3<4||4>5) = {}", ExpressionUtil.calculateExpression("(1>2||2<3)&&(3<4||4>5)").toString());
//逻辑运算
System.out.println("---------------------------------------------------------------------------逻辑运算------------------------------------------------------------------");
logger.info("=> true&&false = {}", ExpressionUtil.calculateExpression("true&&false").toString());
logger.info("=> true||false = {}", ExpressionUtil.calculateExpression("true||false").toString());
logger.info("=> !true = {}", ExpressionUtil.calculateExpression("!true").toString());
logger.info("=> !(7>3) = {}", ExpressionUtil.calculateExpression("!(7>3)"));
// 复杂逻辑运算
System.out.println("---------------------------------------------------------------------------复杂逻辑运算------------------------------------------------------------------");
logger.info("=> ((6>1)||(true&&(6<2))&&((4<7)||(6>=3))) = {}", ExpressionUtil.calculateExpression("((6>1)||(true&&(6<2))&&((4<7)||(6>=3)))"));
// 逻辑和算术混合运算
System.out.println("---------------------------------------------------------------------------逻辑和算术混合运算-----------------------------------------------------");
logger.info("=> (1+2>3&&4/2==2) = {}", ExpressionUtil.calculateExpression("(1+2>3&&4/2==2)"));
logger.info("=> false&&(4/2==2) = {}", ExpressionUtil.calculateExpression("false&&(4/2==2)"));
logger.info("=> true||4/2==2 = {}", ExpressionUtil.calculateExpression("true||4/2==2"));
logger.info("=> (1+2>3&&4/2==2)||(false&&(4/2==2)) = {}", ExpressionUtil.calculateExpression("(1+2>3&&4/2==2)||(false&&(4/2==2))"));
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
测试结果(合理):
-------------------------------------------------------------------------算术运算-------------------------------------------------------------------
18:29:05.084 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1+2 = 3
18:29:05.095 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1-2 = -1
18:29:05.102 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1*2 = 2
18:29:05.109 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1/2 = 0.5
18:29:05.116 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1%2 = 1
-------------------------------------------------------------------------复杂算术运算------------------------------------------------------------------
18:29:05.122 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1+2*3 = 7
18:29:05.127 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1+2*3/4 = 2.5
18:29:05.133 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1+2*(3/4) = 2.5
18:29:05.140 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1+2*(3/4)*5 = 8.5
18:29:05.147 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1+2*(3/4)*5%6 = 2.5
18:29:05.153 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1+2*(3/4)*5%6+7-8/9*10%11 = 0.6111111111111107
18:29:05.160 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => (32+21)%100 =53
18:29:05.166 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 4.2-(32+21)%100 = -48.8
18:29:05.171 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => (32+21)/100 = 0.53
18:29:05.176 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 4.1+(32+21)/100 = 4.63
--------------------------------------------------------------------------关系运算------------------------------------------------------------------
18:29:05.184 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1>2 = false
18:29:05.188 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1<2 = true
18:29:05.192 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1>=2 = false
18:29:05.195 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1<=2 = true
18:29:05.199 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1==2 = false
18:29:05.202 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1===2 = false
18:29:05.207 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1!=2 = true
18:29:05.212 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1!==2 = true
---------------------------------------------------------------------------复杂关系运算------------------------------------------------------------------
18:29:05.218 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1>2&&2>3 = false
18:29:05.226 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1>2&&2<3 = false
18:29:05.233 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => 1>2||2<3 = true
18:29:05.242 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => (1>2||2<3)&&3>4 = false
18:29:05.249 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => (1>2||2<3)&&3<4 = true
18:29:05.258 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => (1>2||2<3)&&(3>4||4<5) = true
18:29:05.267 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => (1>2||2<3)&&(3<4||4>5) = true
---------------------------------------------------------------------------逻辑运算------------------------------------------------------------------
18:29:05.271 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => true&&false = false
18:29:05.277 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => true||false = true
18:29:05.282 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => !true = false
18:29:05.289 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => !(7>3) = false
---------------------------------------------------------------------------复杂逻辑运算------------------------------------------------------------------
18:29:05.311 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => ((6>1)||(true&&(6<2))&&((4<7)||(6>=3))) = true
---------------------------------------------------------------------------逻辑和算术混合运算-----------------------------------------------------
18:29:05.321 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => (1+2>3&&4/2==2) = false
18:29:05.329 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => false&&(4/2==2) = false
18:29:05.340 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => true||4/2==2 = true
18:29:05.350 [main] INFO com.jin.demofunction.test.LegalExpressionTest - => (1+2>3&&4/2==2)||(false&&(4/2==2)) = false
Process finished with exit code 0
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
· 总结
主要实现了基于JS表达式引擎的逻辑和算术混合表达式的计算,目前的封装类支持的运算符如下:
- 小括号 : ()
- 基本四则运算符: +、-、*、/、%
- 判断: >、<、>= 、<=、!=、==
- 布尔运算符: && 、|| 、!
各位小伙伴测试过程若是遇到表达式不合理的情况,请在评论区给我留言,大家一起进步 !!