ExpressionEvaluator
Java Expression Evaluator Library
Install / Use
/learn @Kralite/ExpressionEvaluatorREADME
ExpressionEvaluator
ExpressionEvaluator是一个Java库,用来对表达式进行求值,并且可以很容易地扩展新的运算方法、值类型等。
ExpressionEvaluator已封装了最常用的应用场景:对字符串类型的表达式进行求值。
例如:
要求 a/5 + b * (2 - c + 52.4/3) 这个表达式的值,其中a、b、c是参数,可以向它们赋值。代码如下:
// 定义表达式
String expression = "a/5 + b * (2 - c + 52.4/3)";
// 传入变量值
Map<String, String> params = new TreeMap<>();
params.put("a", "6");
params.put("b", "3");
params.put("c", "49");
try{
Operand result = CommonEvaluator.value(expression, params);
System.out.println("Sample1 result: " + result.value());
}
catch (Exception e) {
e.printStackTrace();
}
求值的结果是:-87.4
除了数值运算外,逻辑运算、字符串拼接、正则表达式、变量名正则匹配等,能满足大多数自定义运算需求。
事实上除了字符串类型的表达式求值,任何自定义类型的都可以使用公共的求值内核,只需要为自定义类型扩展一个解析器(Parser)即可。
Sample.java 提供了3个简单样例供参考。
主要类图

功能及实例教程(字符串类型表达式)
一 字符串类型表达式使用方法
调用CommonEvaluator的静态方法value即可:
/**
* 对字符串类型的表达式求值
* @param expression 表达式
* @param params 参数,用以为表达式中的变量赋值
* @return 计算结果(调用Operand.value()方法可以得到实际值)
* @throws Exception 求值异常
*/
public static Operand value(String expression, Map<String, String> params)
二 变量的表示、加减乘除、逻辑运算和括号
- 变量的表示就直接写它的名字即可:
x > 3
含义:若x这个变量的数值大于3,就返回true:
{x:4}
- 数字类型可以进行加减乘除,以及大于
>、小于<、等于==运算:
a * 2 + b
{x:1, b:2} // 结果为:4
a + 2 == b
{a:1, b:3} //结果为:true
- 字符串可以相加、判断相等。字符串也可以和数字相加拼接。
字符串常量需要用双引号包起来(如
"string"),否则会被认为是变量:
"free" + x + "_" + (2.1 + 1) == "freeaccount_3.1"
{x: "account"} //true
- 支持与
&&、或||、非!逻辑运算。
x == "freeshare" && ( e>0 || (!(c>0)))
{x:freeshare, e:2, c: 1 ...} //true
{x:freelol, e:2, c:1 ...} //false
- 表达式中运算符和运算数之间对空格没有要求,没有空格或任意多个空格都不影响。
- params中可以有表达式中没有出现的变量,但是不能缺少表达式中出现了的变量。
三 正则表达式、复杂变量名、变量名正则匹配
- 支持判断某字符串是否匹配某正则表达式,语法是
str ~ regex("regular expression"),其中str可以是字符串常量也可以是变量名,regex()括号内的正则表达式必须是字符串常量。
x ~ regex("free\w+")
{x: freeshare ...} //true
{x: freelol ...} //true
{x: appstore ...} //false
(x + "@" + e + ".com") ~ regex("\w+@\w+\.com") && c>0
{x: cdl, e:free4inno, c:1} //true
- 复杂变量名:带有+、-、*、/这些和表达式中运算符号相同的变量名会造成歧义,使运算结果出错。这样的变量名可以用
v("fieldName")来包围,就不会出现歧义,其运算效果和直接写变量名完全一样。
v("localhost/srv/nfs4") + v("c++") + x //正确
{
localhost/srv/nfs4 : 2 ,
c++ : 2,
x : 1
}// 结果是:5
localhost/srv/nfs4 + c++ + x //错误
- 变量名正则匹配的含义(此种运算下的结果必须是布尔类型):params中某一变量的名字匹配某正则表达式的的话,就把params中该变量的值代入表达式计算;如果有多个变量的名字都匹配该正则表达式,则会分别把params中这些变量的值代入表达式计算,然后将各表达式的结果作“或”运算得到最后的布尔值。变量名正则匹配的语法是
regV("regex of fieldName")。
regV("192.168.33.\d+:?/srv/nfs4/\.system\.disk\.in_use") + x > 5
//结果为true:
{
192.168.33.6:/srv/nfs4/.system.disk.free : 3, //变量名不匹配
192.168.33.3:/srv/nfs4/.system.disk.in_use : 4, //变量名匹配
192.168.33.3/srv/nfs4/.system.disk.in_use : 5, //变量名匹配
192.168.33.6/srv/nfs4/.system.disk.free : 2, //变量名不匹配
x : 1
...
}
上面这个例子的4个变量中,只有第二个和第三个匹配了正则表达式,所以会分别将5和6代入表达式计算,即分别计算 `4+1>5` 和 `5+1>5` 两个式子,将各自的结果false和true进行逻辑或运算,得到结果为true。
regV("\w+Name") ~ regex("free\w+")
{
appName: freeshare, //appName匹配"\w+Name",freeshare匹配"free\w+",true
groupName: freelol, //groupName匹配"\w+Name",freelol匹配"free\w+",true
userName: cdl, //userName匹配"\w+Name",cdl不匹配"free\w+",false
creator: free4inno //creator不匹配"\w+Name",因此free4inno不参与计算
}
结果会分别将appName、groupName和userName的值代入表达式运算,将各自的结果取“或”得到true。
**注意:**对变量名进行正则匹配实际上是表达式的歧义(同一表达式多个运算结果),为了让结果可控,只支持最多一个变量名的正则匹配,否则计算结果会出现未知错误。例如
regV("\w+price") + regV("\w+ammount") > 5,这个表达式是不允许的。但是如果正则表达式相同,可以在同一表达式中多次出现,如regV("\w+price") + regV("\w+price") > 5,这样是没问题的。
四 向量
向量的语法是 vector(e1, e2, ...) 。
//向量间运算必须维度相同,取两向量同一位置处的元素进行运算,结果是一个同维度的向量
vector(1, 2, 3) * vector(1, 2, 3) //结果是: vector(1, 4, 9) //正确
vector(1, 2, 3) + vector(1, 2, 3, 4) //错误,不同维度向量不能运算
//向量和普通数运算,是把向量各元素分别和该数运算,然后得到一个同纬度向量
vector(1, 2, 3) + 1 // 结果是: vector(2, 3, 4)
vector(1, 2, 3) + 1 + vector(1, 1, 1) > 4 //结果是vector(false,false,true)。
//同一vector中各元素类型不一定要相同,目前暂时只支持字符串、数字和布尔,暂不支持变量。如果使用变量的话请使用“变量名正则匹配”的方法
vector(1,"hello") + 3 //结果是: vector(4,"hello3")
五 优先级表
|优先级|操作符| |:--:|:--:| |5|~(正则表达式匹配)| |4| *、/| |3| +、-| |2| >、<、==| |1| !、&&、|||
Related Skills
node-connect
344.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
99.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
