简单却又极具扩展性的Java表达式引擎
这个表达式引擎只有短短的100多行,却能实现包括加减乘除、括号优先级在内的运算,可以在“处理表达式”函数中自行扩展想要处理的算法。这里面算法的难点主要在于如何实现在多级括号存在的情况下,能取出最外层的一对括号,“成对处理”函数可以广泛的应用在爬虫、数据抓取的软件中。先附上源码:
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Calculate {
private Hashtable 堆栈值 = new Hashtable<>();
private int 表达式游标 = 0;
public static List 成对处理(String code, String start, String end) {
List subResult = new ArrayList<>();
String temp = "";
String nextLevelCode = "";
int level = 0;
for (char codeChar : code.toCharArray()) {
temp += codeChar;
if (temp.endsWith(end)) {
level--;
if (level == 0) {
subResult.add(nextLevelCode.toString());
nextLevelCode = "";
}
}
if (level != 0) {
nextLevelCode += codeChar;
}
if (temp.endsWith(start)) {
level++;
}
}
return subResult;
}
public static List 前置处理(String code, String front) {
front = front.replace("+", "\\+").replace("-", "\\-");
return getMatchList(code, front + "+*");
}
public static List 后置处理(String code, String back) {
back = back.replace("+", "\\+").replace("-", "\\-");
return getMatchList(code, "+*" + back);
}
public static List 运算处理(String code, String calc) {
calc = calc.replace("+", "\\+").replace("*", "\\*").replace("-", "\\-");
return getMatchList(code,
"+[\\.]**" + calc + "**[\\.]**");
}
public Object 处理表达式(String 表达式) throws Exception {
List 子表达式列表 = new ArrayList();
// 先运算括号中的内容
子表达式列表 = 成对处理(表达式, "(", ")");
if (子表达式列表.size() != 0) {
for (String 子表达式 : 子表达式列表) {
Object 子表达式值 = 处理表达式(子表达式);
String 游标键 = "_V" + (表达式游标++);
堆栈值.put(游标键, 子表达式值);
表达式 = 表达式.replace("(" + 子表达式 + ")", 游标键);
}
return 处理表达式(表达式);
}
表达式 = 表达式.replace(" ", "");
// 运算乘法
if (表达式.contains("*"))
子表达式列表 = 运算处理(表达式, "*");
if (子表达式列表.size() != 0) {
for (String 子表达式 : 子表达式列表) {
String 乘数 = 子表达式.split("\\*");
String 被乘数 = 子表达式.split("\\*");
if (乘数.startsWith("_V"))
乘数 = 堆栈值.get(乘数).toString();
if (被乘数.startsWith("_V"))
被乘数 = 堆栈值.get(被乘数).toString();
Object 子表达式值 = Double.parseDouble(乘数) * Double.parseDouble(被乘数);
String 游标键 = "_V" + (表达式游标++);
堆栈值.put(游标键, 子表达式值);
表达式 = 表达式.replace(子表达式, 游标键);
}
return 处理表达式(表达式);
}
// 运算除法
if (表达式.contains("/"))
子表达式列表 = 运算处理(表达式, "/");
if (子表达式列表.size() != 0) {
for (String 子表达式 : 子表达式列表) {
String 乘数 = 子表达式.split("/");
String 被乘数 = 子表达式.split("/");
if (乘数.startsWith("_V"))
乘数 = 堆栈值.get(乘数).toString();
if (被乘数.startsWith("_V"))
被乘数 = 堆栈值.get(被乘数).toString();
Object 子表达式值 = Double.parseDouble(乘数) / Double.parseDouble(被乘数);
String 游标键 = "_V" + (表达式游标++);
堆栈值.put(游标键, 子表达式值);
表达式 = 表达式.replace(子表达式, 游标键);
}
return 处理表达式(表达式);
}
// 运算加法
if (表达式.contains("+"))
子表达式列表 = 运算处理(表达式, "+");
if (子表达式列表.size() != 0) {
for (String 子表达式 : 子表达式列表) {
String 乘数 = 子表达式.split("\\+");
String 被乘数 = 子表达式.split("\\+");
if (乘数.startsWith("_V"))
乘数 = 堆栈值.get(乘数).toString();
if (被乘数.startsWith("_V"))
被乘数 = 堆栈值.get(被乘数).toString();
Object 子表达式值 = Double.parseDouble(乘数) + Double.parseDouble(被乘数);
String 游标键 = "_V" + (表达式游标+www.9ask.cn/cz/+);
堆栈值.put(游标键, 子表达式值);
表达式 = 表达式.replace(子表达式, 游标键);
}
return 处理表达式(表达式);
}
页:
[1]