|
@@ -0,0 +1,97 @@
|
|
|
|
|
+package com.hotent.util;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+import java.util.regex.Matcher;
|
|
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 从表达式提取参数变量
|
|
|
|
|
+ */
|
|
|
|
|
+public class VariableParser {
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从四则运算表达式中提取所有变量
|
|
|
|
|
+ * @param expression 四则运算表达式
|
|
|
|
|
+ * @return 变量名的Set集合
|
|
|
|
|
+ */
|
|
|
|
|
+ public static Set<String> extractVariables(String expression) {
|
|
|
|
|
+ Set<String> variables = new HashSet<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 正则表达式:匹配变量名(字母或下划线开头,后跟字母、数字或下划线)
|
|
|
|
|
+ Pattern pattern = Pattern.compile("[a-zA-Z_.][a-zA-Z0-9_.]*");
|
|
|
|
|
+ Matcher matcher = pattern.matcher(expression);
|
|
|
|
|
+
|
|
|
|
|
+ // JavaScript/数学函数和常量黑名单
|
|
|
|
|
+ Set<String> blacklist = new HashSet<>(Arrays.asList(
|
|
|
|
|
+ "Math", "math",
|
|
|
|
|
+ "sin", "cos", "tan", "cot", "sec", "csc",
|
|
|
|
|
+ "asin", "acos", "atan", "acot",
|
|
|
|
|
+ "sinh", "cosh", "tanh",
|
|
|
|
|
+ "log", "ln", "lg", "exp",
|
|
|
|
|
+ "sqrt", "cbrt", "abs",
|
|
|
|
|
+ "PI", "E", "pi", "e",
|
|
|
|
|
+ "min", "max", "pow", "random"
|
|
|
|
|
+ ));
|
|
|
|
|
+
|
|
|
|
|
+ while (matcher.find()) {
|
|
|
|
|
+ String potentialVar = matcher.group();
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否是黑名单中的数学函数或常量
|
|
|
|
|
+ if (!blacklist.contains(potentialVar)) {
|
|
|
|
|
+ // 检查是否全是数字(虽然正则已经排除了以数字开头的情况,但确保安全)
|
|
|
|
|
+ if (!potentialVar.matches("\\d+")) {
|
|
|
|
|
+ variables.add(potentialVar);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return variables;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 提取变量并统计出现次数
|
|
|
|
|
+ */
|
|
|
|
|
+ public static Map<String, Integer> extractVariablesWithCount(String expression) {
|
|
|
|
|
+ Map<String, Integer> variableCount = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 数学函数和常量黑名单
|
|
|
|
|
+ Set<String> blacklist = new HashSet<>(Arrays.asList(
|
|
|
|
|
+ "Math", "sin", "cos", "tan", "log", "sqrt", "PI", "E"
|
|
|
|
|
+ ));
|
|
|
|
|
+
|
|
|
|
|
+ Pattern pattern = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*");
|
|
|
|
|
+ Matcher matcher = pattern.matcher(expression);
|
|
|
|
|
+
|
|
|
|
|
+ while (matcher.find()) {
|
|
|
|
|
+ String potentialVar = matcher.group();
|
|
|
|
|
+
|
|
|
|
|
+ if (!blacklist.contains(potentialVar) && !potentialVar.matches("\\d+")) {
|
|
|
|
|
+ variableCount.put(potentialVar, variableCount.getOrDefault(potentialVar, 0) + 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return variableCount;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
|
+ String[] testExpressions = {
|
|
|
|
|
+ "(taiyuan.c1+taiyuan.c2)*(c1/c2)+c1",
|
|
|
|
|
+ "a + b * c - d / e",
|
|
|
|
|
+ "sin(x) + cos(y) + log(z)",
|
|
|
|
|
+ "width * height + depth",
|
|
|
|
|
+ "2 * PI * radius",
|
|
|
|
|
+ "temp1 + temp2 - temp3 * temp4",
|
|
|
|
|
+ "var_1 + var_2 * var_test"
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ for (String expr : testExpressions) {
|
|
|
|
|
+ Set<String> variables = extractVariables(expr);
|
|
|
|
|
+ Map<String, Integer> variableCount = extractVariablesWithCount(expr);
|
|
|
|
|
+
|
|
|
|
|
+ System.out.println("表达式: " + expr);
|
|
|
|
|
+ System.out.println("提取的变量: " + variables);
|
|
|
|
|
+ System.out.println("变量出现次数: " + variableCount);
|
|
|
|
|
+ System.out.println();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|