104 lines
3.5 KiB
C#
104 lines
3.5 KiB
C#
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<string, object>? 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<string, object>) PreprocessExpression(
|
|
string expression,
|
|
Dictionary<string, object>? variables)
|
|
{
|
|
if (variables == null || variables.Count == 0)
|
|
return (expression, variables ?? new Dictionary<string, object>());
|
|
|
|
// 生成变量名映射 (中文 -> 英文别名)
|
|
var chineseToAlias = new Dictionary<string, string>();
|
|
var aliasToValue = new Dictionary<string, object>();
|
|
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<string, object>(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);
|
|
}
|
|
}
|
|
} |