using System.Text.RegularExpressions;
using NCalc;
public class Utils
{
#region 打控制台日志
public static void WriteLog(string msg, string filename = "message")
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "--" + filename + "--" + msg);
}
#endregion
///
/// 解析布尔表达式,返回 true/false
/// 支持的表达式示例:"10 > 5", "a == b", "(1+2) < 10 && 3 != 4", "true || false"
///
/// 布尔表达式字符串
/// 可选:表达式中的变量参数(如 a=10, b=5)
/// 表达式的布尔结果
public static bool EvaluateBoolean(string booleanExpression, Dictionary parameters = null)
{
try
{
// 创建表达式对象
var expr = new Expression(booleanExpression);
// 2. 【强制绑定】直接绑定函数事件(不抽离,避免绑定失效)
expr.EvaluateFunction += OnEvaluateFunction;
// 注入变量参数(如果有)
if (parameters != null && parameters.Count > 0)
{
foreach (var param in parameters)
{
expr.Parameters[param.Key] = param.Value;
}
}
// 执行表达式并转换为布尔值
var result = expr.Evaluate();
return Convert.ToBoolean(result);
}
catch (Exception ex)
{
throw new ArgumentException($"布尔表达式解析失败:{booleanExpression},错误:{ex.Message}", ex);
}
}
///
/// 核心函数处理逻辑(直接写,避免任何匹配误差)
///
private static void OnEvaluateFunction(string funcName, FunctionArgs args)
{
// 注册 Contains 函数(核心新增)
if (funcName == "Contains")
{
if (args.Parameters.Length != 2)
{
throw new ArgumentException("Contains 必须传入 2 个参数:字符串、子串");
}
// 安全获取参数(避免 null/空字符串解析问题)
var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
var subStr = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
args.Result = str.Contains(subStr);
return;
}
// 方案1:精准匹配(表达式写 StartsWith 就匹配 StartsWith)
if (funcName == "StartsWith")
{
// 严格校验参数数量
if (args.Parameters.Length != 2)
{
throw new ArgumentException("StartsWith 必须传入 2 个参数:字符串、前缀");
}
// 安全获取参数值(避免 null)
var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
var prefix = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
// 执行原生 StartsWith
args.Result = str.StartsWith(prefix);
return;
}
if (funcName == "EndsWith")
{
// 严格校验参数数量
if (args.Parameters.Length != 2)
{
throw new ArgumentException("EndsWith 必须传入 2 个参数:字符串、前缀");
}
// 安全获取参数值(避免 null)
var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
var prefix = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
// 执行原生 EndsWith
args.Result = str.EndsWith(prefix);
return;
}
// 方案1:精准匹配 IsNullOrEmpty
if (funcName == "IsNullOrEmpty")
{
if (args.Parameters.Length != 1)
{
throw new ArgumentException("IsNullOrEmpty 必须传入 1 个参数:字符串");
}
var value = args.Parameters[0].Evaluate()?.ToString();
args.Result = string.IsNullOrEmpty(value);
return;
}
if (funcName == "Match")
{
// 严格校验参数数量
if (args.Parameters.Length != 2)
{
throw new ArgumentException("StartsWith 必须传入 2 个参数:字符串、前缀");
}
// 安全获取参数值(避免 null)
var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
var prefix = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
// 执行原生 StartsWith
args.Result = Regex.IsMatch(str, prefix);
return;
}
// 未找到函数时明确报错
throw new ArgumentException($"未定义函数:{funcName}");
}
}