轉載:https://www.jb51.net/article/143967.htm
方法一:Java呼叫js方法執行:
/** * * @author: Longjun * @Description: 將${money>=2000&&money<=4000}字串擷取成"money>=2000&&money<=4000", * 然後判斷一個數值字串是否在此區間內 * @date:2016年3月21日 上午11:25:32 */ public static Boolean isInclude(String elValue,String elString){ String el = elString.substring(elString.indexOf("{")+1, elString.indexOf("}")); ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("js"); engine.put("money",elValue); boolean eval = false; try { eval = (boolean) engine.eval(el); } catch (ScriptException e) { // TODO Auto-generated catch block e.printStackTrace(); } return eval; }
方法二:能夠保證四則運算精度
/** * @Project: BizRule * @File: org.coffeesweet.util.MathExpress.java * @Author: coffeesweet * @Date: 2011-3-28 * @Description: 2011 coffeesweet Inc. All rights reserved. */ package org.coffeesweet.util; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author coffeesweet * +,-,*,/四則運算的表示式逆波蘭解析計算類,精確計算,應用BigDecimal類處理 * 支援負數,但規範除整個表示式第一個數為負數時可以不出現在'('後,其它表示式中間任何位置的 * 負數必須出現在'('後,即:用括號括起來。比如:-3+(-2+1)*10或-3+((-2)+1)*10或(-3)+(-2+1)*10或(-3)+((-2)+1)*10 */ public class MathExpress { /** * + */ private final static String OP1 = "+"; /** * - */ private final static String OP2 = "-"; /** * * */ private final static String OP3 = "*"; /** * / */ private final static String OP4 = "/"; /** * ^ */ // private final static String OP5 = "^"; /** * % */ // private final static String OP6 = "%"; /** * ( */ private final static String OPSTART = "("; /** * ) */ private final static String OPEND = ")"; /** * !用來替代負數前面的'-' */ // private final static String NEGATIVESING = "!"; /** * !用來替代負數前面的'+' */ // private final static String PLUSSING = "@"; /** * '#'用來代表運算級別最低的特殊字元 */ // private final static String LOWESTSING = "#"; //最原始的四則運算式 private String expBase; //經過初始化處理後的四則運算式 private String expInited; //精度 private int precision=10; //取捨模式 private RoundingMode roundingMode=RoundingMode.HALF_UP; //精度上下文 private MathContext mc; //四則運算解析 private List<String> expList = new ArrayList<String>(); //存放逆波蘭表示式 private List<String> rpnList = new ArrayList<String>(); public MathExpress(){ } public MathExpress(String expBase) { init(expBase,this.precision,this.roundingMode); } public MathExpress(String expBase,int precision,RoundingMode roundingMode){ init(expBase,precision,roundingMode); } public void init(String expBase,int precision,RoundingMode roundingMode){ this.expBase = expBase; this.precision = precision; this.roundingMode = roundingMode; this.mc = new MathContext(precision,roundingMode); this.expInited = initExpress(expBase); StringTokenizer st = new StringTokenizer(this.expInited,"+-*/^%()",true); while(st.hasMoreElements()){ this.expList.add(st.nextElement().toString().trim()); } this.rpnList = initRPN(this.expList); } /** * @return the expBase */ public String getExpBase() { return expBase; } /** * @param expBase the expBase to set */ public void setExpBase(String expBase) { this.expBase = expBase; } /** * @return the expInited */ public String getExpInited() { return expInited; } /** * @param expInited the expInited to set */ public void setExpInited(String expInited) { this.expInited = expInited; } /** * @return the precision */ public int getPrecision() { return precision; } /** * @param precision the precision to set */ public void setPrecision(int precision) { this.precision = precision; } /** * @return the roundingMode */ public RoundingMode getRoundingMode() { return roundingMode; } /** * @param roundingMode the roundingMode to set */ public void setRoundingMode(RoundingMode roundingMode) { this.roundingMode = roundingMode; } /** * @return the expList */ public List<String> getExpList() { return expList; } /** * @param expList the expList to set */ public void setExpList(List<String> expList) { this.expList = expList; } /** * @return the rpnList */ public List<String> getRpnList() { return rpnList; } /** * @param rpnList the rpnList to set */ public void setRpnList(List<String> rpnList) { this.rpnList = rpnList; } /** * @return the mc */ public MathContext getMc() { return mc; } /** * @param mc the mc to set */ public void setMc(MathContext mc) { this.mc = mc; } /** * 去除空白字元和在負號'-'前加'0',便於後面的StringTokenizer * @param exp * @return */ private static String initExpress(String exp){ String reStr = null; reStr = exp.replaceAll("\\s", ""); if(reStr.startsWith("-")){ reStr = "0"+reStr; } reStr = reStr.replaceAll("\\(\\-", "(0-"); return reStr; } /** * 是否是整數或是浮點數,但預設-05.15這種也認為是正確的格式 * @param str * @return */ private boolean isNumber(String str){ Pattern p = Pattern.compile("^(-?\\d+)(\\.\\d+)?$"); Matcher m = p.matcher(str); boolean isNumber = m.matches(); return isNumber; } /** * 設定優先順序順序()設定與否無所謂 * @param sign * @return */ private int precedence(String str){ char sign = str.charAt(0); switch(sign){ case '+': case '-': return 1; case '*': case '/': return 2; case '^': case '%': return 3; case '(': case ')': // case '#': default: return 0; } } /** * 轉變為逆波蘭表示式 * @param strList * @return */ public List<String> initRPN(List<String> strList){ List<String> returnList = new ArrayList<String>(); //用來存放操作符的棧 Stack stack = new Stack(); // stack.push(LOWESTSING); int length = strList.size(); for(int i=0;i<length;i++ ){ String str = strList.get(i); if(isNumber(str)){ returnList.add(str); }else{ if(str.equals(OPSTART)){ //'('直接入棧 stack.push(str); }else if(str.equals(OPEND)){ //')' //進行出棧操作,直到棧為空或者遇到第一個左括號 while (!stack.isEmpty()) { //將棧頂字串做出棧操作 String tempC = stack.pop(); if (!tempC.equals(OPSTART)) { //如果不是左括號,則將字串直接放到逆波蘭連結串列的最後 returnList.add(tempC); }else{ //如果是左括號,退出迴圈操作 break; } } }else{ if (stack.isEmpty()) { //如果棧內為空 //將當前字串直接壓棧 stack.push(str); }else{ //棧不空,比較運算子優先順序順序 if(precedence(stack.top())>=precedence(str)){ //如果棧頂元素優先順序大於當前元素優先順序則 while(!stack.isEmpty() && precedence(stack.top())>=precedence(str)){ returnList.add(stack.pop()); } } stack.push(str); } } } } //如果棧不為空,則將棧中所有元素出棧放到逆波蘭連結串列的最後 while (!stack.isEmpty()) { returnList.add(stack.pop()); } return returnList; } /** * 計算逆波蘭表示式 * @param rpnList * @return */ public String caculate(List<String> rpnList){ Stack numberStack = new Stack(); int length=rpnList.size(); for(int i=0;i<length;i++){ String temp=rpnList.get(i); if(isNumber(temp)){ numberStack.push(temp); }else{ BigDecimal tempNumber1 = new BigDecimal(numberStack.pop(),this.mc); BigDecimal tempNumber2 = new BigDecimal(numberStack.pop(),this.mc); BigDecimal tempNumber = new BigDecimal("0",this.mc); if(temp.equals(OP1)){ tempNumber=tempNumber2.add(tempNumber1); }else if(temp.equals(OP2)){ tempNumber=tempNumber2.subtract(tempNumber1); }else if(temp.equals(OP3)){ tempNumber=tempNumber2.multiply(tempNumber1); }else if(temp.equals(OP4)){ tempNumber=tempNumber2.divide(tempNumber1, precision, roundingMode); } numberStack.push(tempNumber.toString()); } } return numberStack.pop(); } /** * 按照類的預設引數進行計算 * @return */ public String caculate(){ return caculate(this.rpnList); } /** * 數字條件表示式精確比較 * eg: "3.0>2" "1<5" "1==5" "1!=5" "(1.0+2)>3" "((-0.9+3)>=2. 1)" * 不支援&&,||等連線符 * @param str * @return */ public static boolean compareTo(String strParm){ boolean reBoolean = false; boolean isParentheses = false;//標記是否有()括上整個字串 String str = initExpress(strParm); Pattern p = Pattern.compile("^\\([\\s\\S]*\\)$"); Matcher m = p.matcher(str); isParentheses = m.matches(); if(-1==str.indexOf(">=")&&-1==str.indexOf("<=")&&-1==str.indexOf("==")&&-1==str.indexOf("!=")){ if(-1==str.indexOf(">")&&-1==str.indexOf("<")) throw new IllegalArgumentException("異常:條件表示式不正確!"); } if(-1 != str.indexOf(">=")){ String[] strTemps = str.split(">="); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( -1 == r ){ reBoolean = false; }else{ reBoolean = true; } }else if(-1 != str.indexOf("<=")){ String[] strTemps = str.split("<="); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( 1 == r ){ reBoolean = false; }else{ reBoolean = true; } }else if(-1 != str.indexOf("==")){ String[] strTemps = str.split("=="); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( 0 == r ){ reBoolean = true; }else{ reBoolean = false; } }else if(-1 != str.indexOf("!=")){ String[] strTemps = str.split("!="); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( 0 != r ){ reBoolean = true; }else{ reBoolean = false; } }else if((-1 != str.indexOf(">")) && (-1 == str.indexOf("="))){ String[] strTemps = str.split(">"); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( 1 == r ){ reBoolean = true; }else{ reBoolean = false; } }else if((-1 != str.indexOf("<")) && (-1 == str.indexOf("="))){ String[] strTemps = str.split("<"); if(isParentheses){ strTemps[0] = strTemps[0] + ")"; strTemps[1] = "(" + strTemps[1]; } int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate()))); if( -1 == r ){ reBoolean = true; }else{ reBoolean = false; } } return reBoolean; } public static void main(String...args){ // MathExpress me = new MathExpress("-(-0.5+0.1)*10+2",10,RoundingMode.HALF_UP); // System.out.println(me.getExpList()); // List<String> tempList = me.initRPN(me.getExpList()); // System.out.println(tempList); // String resultStr = me.caculate(tempList); // System.out.println(resultStr); MathExpress me = new MathExpress("-(-1.5000000003+0.1)*10+2"); String resultStr = me.caculate(); BigDecimal bd = new BigDecimal(resultStr); BigDecimal bd2 = bd.setScale(2, RoundingMode.HALF_UP); System.out.println(me.caculate()); System.out.println(bd.toString()); System.out.println(bd.scale()); System.out.println(bd2.toString()); System.out.println(bd2.scale()); // System.out.println("------------------------------------"); // Pattern p = Pattern.compile("^\\([\\s\\S]*\\)$");//匹配類似以'('開頭')'結尾的字串 // Matcher m = p.matcher("(2. 0>2.22)"); // System.out.println(m.matches()); boolean reBoolean = MathExpress.compareTo("((-8.0+3)>=2. 1)"); System.out.println(reBoolean); } /** * 棧 */ private class Stack { LinkedList<String> stackList = new LinkedList<String>(); public Stack() { } /** * 入棧 * @param expression */ public void push(String expression) { stackList.addLast(expression); } /** * 出棧 * @return */ public String pop() { return stackList.removeLast(); } /** * 棧頂元素 * @return */ public String top() { return stackList.getLast(); } /** * 棧是否為空 * @return */ public boolean isEmpty() { return stackList.isEmpty(); } } }
方法三:https://blog.csdn.net/u012468264/article/details/56679802