using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using NCalc; namespace Common.Tools { public class ExpressionEvaluator { public static bool EvaluateExpression(string expression, Dictionary? variables = null) { try { // 预处理:替换中文变量名为英文别名 var (processedExpression, processedVariables) = PreprocessExpression(expression, variables); var expr = new Expression(processedExpression, EvaluateOptions.IgnoreCase); if (processedVariables != null) { foreach (var kvp in processedVariables) { expr.Parameters[kvp.Key] = kvp.Value; } } if (expr.HasErrors()) { throw new ArgumentException($"条件表达式格式错误: {expr.Error}"); } var result = expr.Evaluate(); return Convert.ToBoolean(result); } catch (Exception ex) { throw new ArgumentException($"条件表达式异常: {ex.Message}"); } } private static (string, Dictionary) PreprocessExpression( string expression, Dictionary? variables) { if (variables == null || variables.Count == 0) return (expression, variables ?? new Dictionary()); // 生成变量名映射 (中文 -> 英文别名) var chineseToAlias = new Dictionary(); var aliasToValue = new Dictionary(); int counter = 1; foreach (var key in variables.Keys) { if (ContainsChinese(key)) { string alias = $"var_{counter}"; counter++; chineseToAlias[key] = alias; aliasToValue[alias] = variables[key]; } } // 如果没有中文变量名,直接返回原始数据 if (chineseToAlias.Count == 0) return (expression, variables); // 替换表达式中的中文变量名 string processedExpression = expression; foreach (var pair in chineseToAlias) { // 使用正则确保完整匹配变量名 string pattern = $@"\b{Regex.Escape(pair.Key)}\b"; processedExpression = Regex.Replace( processedExpression, pattern, pair.Value, RegexOptions.Compiled ); } // 创建新变量字典(英文别名 + 原始英文变量) var newVariables = new Dictionary(aliasToValue); foreach (var key in variables.Keys) { if (!ContainsChinese(key)) { newVariables[key] = variables[key]; } } return (processedExpression, newVariables); } // 检查字符串是否包含中文字符 private static bool ContainsChinese(string text) { return text.Any(c => c >= 0x4E00 && c <= 0x9FFF); } } }