Aviator—Java表示式求值引擎的使用
阿新 • • 發佈:2020-09-12
pom
<dependency> <groupId>com.googlecode.aviator</groupId> <artifactId>aviator</artifactId> <version>4.2.10</version> </dependency>
對map的操作
import java.util.HashMap; import java.util.Map; import com.googlecode.aviator.AviatorEvaluator; importcom.googlecode.aviator.runtime.function.AbstractFunction; import com.googlecode.aviator.runtime.function.FunctionUtils; import com.googlecode.aviator.runtime.type.AviatorBigInt; import com.googlecode.aviator.runtime.type.AviatorObject; public class App { static{ //註冊函式 AviatorEvaluator.addFunction(newMinFunction()); } public static void main( String[] args ) { Map<String, Object> sourceMapItem = new HashMap<String, Object>(); sourceMapItem.put("pt", "mi"); sourceMapItem.put("ab", "abc"); sourceMapItem.put("xy", "xyz"); sourceMapItem.put("int1", 135); sourceMapItem.put("int2", 68); sourceMapItem.put("decimal2", 19.83); sourceMapItem.put("mydate", "2020-10-10 28:35:00"); sourceMapItem.put("value", 999); String expStr = "pt == 'mi'"; Object result; result = AviatorEvaluator.execute(expStr, sourceMapItem); System.out.println(expStr+" --- "+result); //邏輯與 + 簡單表示式 expStr = "pt == 'mi' && ab == 'abc' && int1 > 100 && decimal2 < 20.50"; result = AviatorEvaluator.execute(expStr, sourceMapItem); System.out.println(expStr+" --- "+result); //邏輯與或組合 expStr = "pt == 'mi1' || (decimal2 < 20.50 && xy+'X' == 'xyzX')"; result = AviatorEvaluator.execute(expStr, sourceMapItem); System.out.println(expStr+" --- "+result); //三目運算 expStr = "pt == 'mi1' ? ab == 'ab' : ab == 'abc'"; result = AviatorEvaluator.execute(expStr, sourceMapItem); System.out.println(expStr+" --- "+result); //函式 expStr = "pt != 'mi1' && string.length(xy) >= 5 "; result = AviatorEvaluator.execute(expStr, sourceMapItem); System.out.println(expStr+" --- "+result); //自定義函式 expStr = "pt == 'mi1' || myMin(int2 , int1) > 10 "; result = AviatorEvaluator.execute(expStr, sourceMapItem); System.out.println(expStr+" --- "+result); } static class MinFunction extends AbstractFunction { @Override public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) { Number left = FunctionUtils.getNumberValue(arg1, env); Number right = FunctionUtils.getNumberValue(arg2, env); return new AviatorBigInt(Math.min(left.doubleValue(), right.doubleValue())); } public String getName() { return "myMin"; } } }
輸出結果
pt == 'mi' --- true pt == 'mi' && ab == 'abc' && int1 > 100 && decimal2 < 20.50 --- true pt == 'mi1' || (decimal2 < 20.50 && xy+'X' == 'xyzX') --- true pt == 'mi1' ? ab == 'ab' : ab == 'abc' --- true pt != 'mi1' && string.length(xy) >= 5 --- false pt == 'mi1' || myMin(int2 , int1) > 10 --- true
操作符列表
序號 | 操作符 | 結合性 | 運算元限制 |
---|---|---|---|
0 | () [ ] | 從左到右 | ()用於函式呼叫,[ ]用於陣列和java.util.List的元素訪問,要求[indx]中的index必須為整型 |
1 | ! - ~ | 從右到左 | ! 能用於Boolean,- 僅能用於Number,~僅能用於整數 |
2 | * / % | 從左到右 | Number之間 |
3 | + - | 從左到右 | + - 都能用於Number之間, + 還能用於String之間,或者String和其他物件 |
4 | << >> >>> | 從左到右 | 僅能用於整數 |
5 | < <= > >= | 從左到右 | Number之間、String之間、Pattern之間、變數之間、其他型別與nil之間 |
6 | == != =~ | 從左到右 | ==和!=作用於Number之間、String之間、Pattern之間、變數之間、其他型別與nil之間以及String和java.util.Date之間,=~僅能作用於String和Pattern之間 |
7 | & | 從左到右 | 整數之間 |
8 | ^ | 從左到右 | 整數之間 |
9 | ¦ | 從左到右 | 整數之間 |
10 | && | 從左到右 | Boolean之間,短路 |
11 | ¦¦ | 從左到右 | Boolean之間,短路 |
12 | ? : | 從右到左 | 第一個運算元的結果必須為Boolean,第二和第三運算元結果無限制 |
內建函式
函式名稱 | 說明 |
---|---|
sysdate() | 返回當前日期物件java.util.Date |
rand() | 返回一個介於0-1的隨機數,double型別 |
print([out],obj) | 列印物件,如果指定out,向out列印,否則輸出到控制檯 |
println([out],obj) | 與print類似,但是在輸出後換行 |
now() | 返回System.currentTimeMillis |
long(v) | 將值的型別轉為long |
double(v) | 將值的型別轉為double |
str(v) | 將值的型別轉為string |
date_to_string(date,format) | 將Date物件轉化化特定格式的字串,2.1.1新增 |
string_to_date(source,format) | 將特定格式的字串轉化為Date物件,2.1.1新增 |
string.contains(s1,s2) | 判斷s1是否包含s2,返回Boolean |
string.length(s) | 求字串長度,返回Long |
string.startsWith(s1,s2) | s1是否以s2開始,返回Boolean |
string.endsWith(s1,s2) | s1是否以s2結尾,返回Boolean |
string.substring(s,begin[,end]) | 擷取字串s,從begin到end,end如果忽略的話,將從begin到結尾,與java.util.String.substring一樣。 |
string.indexOf(s1,s2) | java中的s1.indexOf(s2),求s2在s1中的起始索引位置,如果不存在為-1 |
string.split(target,regex,[limit]) | Java裡的String.split方法一致,2.1.1新增函式 |
string.join(seq,seperator) | 將集合seq裡的元素以seperator為間隔連線起來形成字串,2.1.1新增函式 |
string.replace_first(s,regex,replacement) | Java裡的String.replaceFirst 方法,2.1.1新增 |
string.replace_all(s,regex,replacement) | Java裡的String.replaceAll方法 ,2.1.1新增 |
math.abs(d) | 求d的絕對值 |
math.sqrt(d) | 求d的平方根 |
math.pow(d1,d2) | 求d1的d2次方 |
math.log(d) | 求d的自然對數 |
math.log10(d) | 求d以10為底的對數 |
math.sin(d) | 正弦函式 |
math.cos(d) | 餘弦函式 |
math.tan(d) | 正切函式 |
map(seq,fun) | 將函式fun作用到集合seq每個元素上,返回新元素組成的集合 |
filter(seq,predicate) | 將謂詞predicate作用在集合的每個元素上,返回謂詞為true的元素組成的集合 |
count(seq) | 返回集合大小 |
include(seq,element) | 判斷element是否在集合seq中,返回boolean值 |
sort(seq) | 排序集合,僅對陣列和List有效,返回排序後的新集合 |
reduce(seq,fun,init) | fun接收兩個引數,第一個是集合元素,第二個是累積的函式,本函式用於將fun作用在集合每個元素和初始值上面,返回最終的init值 |
seq.eq(value) | 返回一個謂詞,用來判斷傳入的引數是否跟value相等,用於filter函式,如filter(seq,seq.eq(3)) 過濾返回等於3的元素組成的集合 |
seq.neq(value) | 與seq.eq類似,返回判斷不等於的謂詞 |
seq.gt(value) | 返回判斷大於value的謂詞 |
seq.ge(value) | 返回判斷大於等於value的謂詞 |
seq.lt(value) | 返回判斷小於value的謂詞 |
seq.le(value) | 返回判斷小於等於value的謂詞 |
seq.nil() | 返回判斷是否為nil的謂詞 |
seq.exists() | 返回判斷不為nil的謂詞 |
常量和變數
值 | 說明 |
---|---|
true | 真值 |
false | 假值 |
nil | 空值 |
$digit |
正則表示式匹配成功後的分組,$0 表示匹配的字串,$1 表示第一個分組 etc. |
參考資料
5.0版以後成為了aviatorscript
https://github.com/killme2008/aviatorscript