Commit 600a1ace authored by yanzg's avatar yanzg

打印模板处理

parent 6af8c54c
package com.yanzuoguang.util.helper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 公式计算
*
* @author 颜佐光
*/
public class CalcHelper {
private static final String REGEX_DOUBLE = "^[-+]?[0-9]*\\.?[0-9]+$";
private static final String REGEX_QUOT = "(^.*?)\\((.+?)\\)(.*?$)";
private static final String REGEX_CALC_ADD_PLUS = "(^.*?)([+\\-])(.*?$)";
private static final String REGEX_CALC_MULTIPLY_MOD = "(^.*?)([*/])(.*?$)";
private static final String REGEX_CALC_TAG = "[+\\-*/()]+";
private static final String EMPTY_CHAR = " ";
/**
* 公式参数获取
*/
public interface CalcParameter {
/**
* 获取参数值
*
* @param parameterName 获取参数值的名称
* @return
*/
double getValue(String parameterName);
}
/**
* 计算公式
*
* @param formula 公式内容,支持括号、空格、数字、+、-、*、/、变量名,如: A * ( B + C )
* @param calcParameter 获取变量值
* @return 运算后的结果
*/
public static double calc(String formula, CalcParameter calcParameter) {
if (StringHelper.isEmpty(formula)) {
return 0;
}
// 去掉公式空格
formula = formula.replaceAll(EMPTY_CHAR, "");
// 获取所有的变量名称
List<String> varNames = getVarNames(formula);
// 获取所有变量值
Map<String, Double> varValues = getVarValues(varNames, calcParameter);
// 返回计算结果
return calcProc(formula, varValues);
}
/**
* 获取变量表
*
* @param formula 输入等式的右边
**/
private static List<String> getVarNames(String formula) {
List<String> list = new ArrayList<>();
//清理所有运算符,并且包含多个运算符号时,将多个运算符号当成一个运算符号处理
String formulaTo = formula.replaceAll(REGEX_CALC_TAG, EMPTY_CHAR);
String[] items = formulaTo.split(EMPTY_CHAR);
for (String item : items) {
// 判断是否是空字符串、纯数字,是则不属于变量
if (StringHelper.isEmpty(item) || item.matches(REGEX_DOUBLE)) {
continue;
}
list.add(item);
}
return list;
}
/**
* 获取所有变量值
*
* @param varNames 变量名称列表
* @param calcParameter 获取变量值
* @return 变量值
*/
private static Map<String, Double> getVarValues(List<String> varNames, CalcParameter calcParameter) {
// 获取所有的变量值
Map<String, Double> varValues = new HashMap<>();
for (String name : varNames) {
if (varValues.containsKey(name)) {
continue;
}
double value = calcParameter.getValue(name);
varValues.put(name, value);
}
return varValues;
}
/**
* 最终计算结果
*
* @param formula 公式
* @param varValues 变量值
* @return
*/
private static double calcProc(String formula, Map<String, Double> varValues) {
if (formula.matches(REGEX_QUOT)) {
// 获取第一个括号和最后一个括号
Pattern p = Pattern.compile(REGEX_QUOT);
Matcher matcher = p.matcher(formula);
if(!matcher.find()){
throw new RuntimeException("正则表达式错误");
}
String left = matcher.group(1);
String quot = matcher.group(2);
String right = matcher.group(3);
double quotResult = calcProc(quot, varValues);
if (!StringHelper.isEmpty(left)) {
// 左边的值
double leftResult = calcProc(StringHelper.left(left, left.length() - 1), varValues);
// 左边和括号中的值计算
quotResult = calcItem(StringHelper.right(left, 1), leftResult, quotResult);
}
if (!StringHelper.isEmpty(right)) {
// 右边的值
double rightResult = calcProc(StringHelper.right(right, left.length() - 1), varValues);
// 左边和括号中的值计算
quotResult = calcItem(StringHelper.left(right, 1), quotResult, rightResult);
}
return quotResult;
} else if (formula.matches(REGEX_CALC_ADD_PLUS)) {
// 判断是否包含+-运算符号
Pattern p = Pattern.compile(REGEX_CALC_ADD_PLUS);
Matcher matcher = p.matcher(formula);
if(!matcher.find()){
throw new RuntimeException("正则表达式错误");
}
double leftResult = calcProc(matcher.group(1),varValues);
double rightResult = calcProc(matcher.group(3),varValues);
return calcItem(matcher.group(2), leftResult,rightResult);
} else if (formula.matches(REGEX_CALC_MULTIPLY_MOD)) {
// 判断是否包含*/运算符号
Pattern p = Pattern.compile(REGEX_CALC_MULTIPLY_MOD);
Matcher matcher = p.matcher(formula);
if(!matcher.find()){
throw new RuntimeException("正则表达式错误");
}
double leftResult = calcProc(matcher.group(1),varValues);
double rightResult = calcProc(matcher.group(3),varValues);
return calcItem(matcher.group(2), leftResult,rightResult);
} else if (formula.matches(REGEX_DOUBLE)) {
return StringHelper.toDouble(formula);
} else {
return varValues.get(formula);
}
}
private static double calcItem(String flag, double a, double b) {
switch (flag) {
case "+":
return a + b;
case "-":
return a - b;
case "*":
return a * b;
case "/":
return a / b;
default:
return 0;
}
}
}
package helper;
import com.yanzuoguang.util.helper.ByteHelper;
import com.yanzuoguang.util.helper.CalcHelper;
import org.junit.Test;
public class TestCalcHelper implements CalcHelper.CalcParameter {
@Test
public void test() {
System.out.println(CalcHelper.calc("2 * ( a + b * d )",this));
}
@Override
public double getValue(String parameterName) {
System.out.println("参数名:" +parameterName);
switch (parameterName){
case "a":
return 5;
case "b":
return 3;
case "d":
return 11;
default:
return 0;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment