设为首页收藏本站

 找回密码
 注册论坛

QQ登录

只需一步,快速开始

用百度帐号登录

只需两步,快速登录

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 389|回复: 0

简单却又极具扩展性的Java表达式引擎

[复制链接]

签到天数: 36 天

[LV.5]常住居民I

发表于 2016/12/30 16:34 | 显示全部楼层 |阅读模式 |Google Chrome 45.0.2454.101|Windows 7
天涯海角搜一下: 百度 谷歌 360 搜狗 有道 雅虎 必应 即刻
这个表达式引擎只有短短的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 + "[_a-zA-Z\\u4E00-\\u9FA5]+[0-9]*");
}

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

public static List 运算处理(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 子表达式列表 = 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" + (表达式游标+www.9ask.cn/cz/+);
堆栈值.put(游标键, 子表达式值);
表达式 = 表达式.replace(子表达式, 游标键);
}
return 处理表达式(表达式);
}
欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册论坛 用百度帐号登录新浪微博账号登陆

本版积分规则

手机版|Archiver|Mail me|网站地图|IT技术交流论坛 ( 闽ICP备13013206号-7 )

GMT+8, 2018/10/16 01:19 , Processed in 0.554393 second(s), 47 queries , Gzip On, Memcache On.

Powered by itzmx!

© 2011-2018 sakura

快速回复 返回顶部 返回列表