最简单却又极具扩展性的Java表达式引擎,自创编程语言必备

这个表达式引擎只有短短的100多行,却能实现包括加减乘除、括号优先级在内的运算,能够在“处理表达式”函数中自行扩展想要处理的算法。这里面算法的难点主要在于如何实如今多级括号存在的状况下,能取出最外层的一对括号,“成对处理”函数能够普遍的应用在爬虫、数据抓取的软件中。java


很少说,先上源码算法

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<String, Object> 堆栈值 = new Hashtable<>();
	private int 表达式游标 = 0;

	public static List<String> 成对处理(String code, String start, String end) {
		List<String> 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> 前置处理(String code, String front) {
		front = front.replace("+", "\\+").replace("-", "\\-");
		return getMatchList(code, front + "[_a-zA-Z\\u4E00-\\u9FA5]+[0-9]*");
	}

	public static List<String> 后置处理(String code, String back) {
		back = back.replace("+", "\\+").replace("-", "\\-");
		return getMatchList(code, "[_a-zA-Z\\u4E00-\\u9FA5]+[0-9]*" + back);
	}

	public static List<String> 运算处理(String code, String calc) {
		calc = calc.replace("+", "\\+").replace("*", "\\*").replace("-", "\\-");
		return getMatchList(code,
				"[_a-zA-Z0-9\\u4E00-\\u9FA5]+[\\.]*[0-9]*" + calc + "[_a-zA-Z\\u4E00-\\u9FA5]*[0-9]*[\\.]*[0-9]*");
	}

	public Object 处理表达式(String 表达式) throws Exception {

		List<String> 子表达式列表 = new ArrayList();

		// 先运算括号中的内容
		子表达式列表 = 成对处理(表达式, "(", ")");
		if (子表达式列表.size() != 0) {
			for (String 子表达式 : 子表达式列表) {
				Object 子表达式值 = 处理表达式(子表达式);
				String 游标键 = "_V" + (表达式游标++);
				堆栈值.put(游标键, 子表达式值);
				表达式 = 表达式.replace("(" + 子表达式 + ")", 游标键);
			}
			return 处理表达式(表达式);
		}

		表达式 = 表达式.replace(" ", "");

		// 运算乘法
		if (表达式.contains("*"))
			子表达式列表 = 运算处理(表达式, "*");
		if (子表达式列表.size() != 0) {
			for (String 子表达式 : 子表达式列表) {
				String 乘数 = 子表达式.split("\\*")[0];
				String 被乘数 = 子表达式.split("\\*")[1];
				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("/")[0];
				String 被乘数 = 子表达式.split("/")[1];
				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("\\+")[0];
				String 被乘数 = 子表达式.split("\\+")[1];
				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("\\-")[0];
				String 被乘数 = 子表达式.split("\\-")[1];
				if (乘数.startsWith("_V"))
					乘数 = 堆栈值.get(乘数).toString();
				if (被乘数.startsWith("_V"))
					被乘数 = 堆栈值.get(被乘数).toString();
				Object 子表达式值 = Double.parseDouble(乘数) - Double.parseDouble(被乘数);
				String 游标键 = "_V" + (表达式游标++);
				堆栈值.put(游标键, 子表达式值);
				表达式 = 表达式.replace(子表达式, 游标键);
			}
			return 处理表达式(表达式);
		}

		// 若是到最后是一个变量,则直接返回变量值
		if (表达式.matches("_V[0-9]+")) {
			return 堆栈值.get(表达式).toString();
		}

		throw new Exception("没法处理的表达式:" + 表达式);
	}

	public static List<String> getMatchList(String managers, String match) {
		List<String> ls = new ArrayList<String>();
		Pattern pattern = Pattern.compile(match);
		Matcher matcher = pattern.matcher(managers);
		while (matcher.find())
			ls.add(matcher.group());
		return ls;
	}
}

测试程序:

public class Test {
	public static void main(String args[]) throws Exception{
		String 表达式="100.25+ (100 /( 25+ 12.5*2))+50/(23+(1+1))";
		System.out.println(new Calculate().处理表达式(表达式));
	}
}
输出结果:104.25