Utils.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. using System.Text.RegularExpressions;
  2. using NCalc;
  3. public class Utils
  4. {
  5. public static Dictionary<string, string> FeignUrl = new Dictionary<string, string>();
  6. #region 打控制台日志
  7. public static void WriteLog(string msg, string filename = "message")
  8. {
  9. Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "--" + filename + "--" + msg);
  10. }
  11. #endregion
  12. /// <summary>
  13. /// 解析布尔表达式,返回 true/false
  14. /// 支持的表达式示例:"10 > 5", "a == b", "(1+2) < 10 && 3 != 4", "true || false"
  15. /// </summary>
  16. /// <param name="booleanExpression">布尔表达式字符串</param>
  17. /// <param name="parameters">可选:表达式中的变量参数(如 a=10, b=5)</param>
  18. /// <returns>表达式的布尔结果</returns>
  19. public static bool EvaluateBoolean(string booleanExpression, Dictionary<string, object> parameters = null)
  20. {
  21. try
  22. {
  23. // 创建表达式对象
  24. var expr = new Expression(booleanExpression);
  25. // 2. 【强制绑定】直接绑定函数事件(不抽离,避免绑定失效)
  26. expr.EvaluateFunction += OnEvaluateFunction;
  27. // 注入变量参数(如果有)
  28. if (parameters != null && parameters.Count > 0)
  29. {
  30. foreach (var param in parameters)
  31. {
  32. expr.Parameters[param.Key] = param.Value;
  33. }
  34. }
  35. // 执行表达式并转换为布尔值
  36. var result = expr.Evaluate();
  37. return Convert.ToBoolean(result);
  38. }
  39. catch (Exception ex)
  40. {
  41. throw new ArgumentException($"布尔表达式解析失败:{booleanExpression},错误:{ex.Message}", ex);
  42. }
  43. }
  44. /// <summary>
  45. /// 核心函数处理逻辑(直接写,避免任何匹配误差)
  46. /// </summary>
  47. private static void OnEvaluateFunction(string funcName, FunctionArgs args)
  48. {
  49. // 注册 Contains 函数(核心新增)
  50. if (funcName == "Contains")
  51. {
  52. if (args.Parameters.Length != 2)
  53. {
  54. throw new ArgumentException("Contains 必须传入 2 个参数:字符串、子串");
  55. }
  56. // 安全获取参数(避免 null/空字符串解析问题)
  57. var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
  58. var subStr = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
  59. args.Result = str.Contains(subStr);
  60. return;
  61. }
  62. // 方案1:精准匹配(表达式写 StartsWith 就匹配 StartsWith)
  63. if (funcName == "StartsWith")
  64. {
  65. // 严格校验参数数量
  66. if (args.Parameters.Length != 2)
  67. {
  68. throw new ArgumentException("StartsWith 必须传入 2 个参数:字符串、前缀");
  69. }
  70. // 安全获取参数值(避免 null)
  71. var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
  72. var prefix = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
  73. // 执行原生 StartsWith
  74. args.Result = str.StartsWith(prefix);
  75. return;
  76. }
  77. if (funcName == "EndsWith")
  78. {
  79. // 严格校验参数数量
  80. if (args.Parameters.Length != 2)
  81. {
  82. throw new ArgumentException("EndsWith 必须传入 2 个参数:字符串、前缀");
  83. }
  84. // 安全获取参数值(避免 null)
  85. var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
  86. var prefix = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
  87. // 执行原生 EndsWith
  88. args.Result = str.EndsWith(prefix);
  89. return;
  90. }
  91. if (funcName == "In")
  92. {
  93. // 严格校验参数数量
  94. if (args.Parameters.Length != 2)
  95. {
  96. throw new ArgumentException("In 必须传入 2 个参数:字符串、前缀");
  97. }
  98. // 安全获取参数值(避免 null)
  99. var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
  100. var prefix = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
  101. // 执行原生 EndsWith
  102. args.Result = str.Replace("[", "").Replace("]", "").Split(',').Contains(prefix);
  103. return;
  104. }
  105. // 方案1:精准匹配 IsNullOrEmpty
  106. if (funcName == "IsNullOrEmpty")
  107. {
  108. if (args.Parameters.Length != 1)
  109. {
  110. throw new ArgumentException("IsNullOrEmpty 必须传入 1 个参数:字符串");
  111. }
  112. var value = args.Parameters[0].Evaluate()?.ToString();
  113. args.Result = string.IsNullOrEmpty(value);
  114. return;
  115. }
  116. if (funcName == "ArrayLen")
  117. {
  118. if (args.Parameters.Length != 1)
  119. {
  120. throw new ArgumentException("ArrayLen 必须传入 1 个参数:数组");
  121. }
  122. var value = args.Parameters[0].Evaluate()?.ToString();
  123. args.Result = value?.Replace("[", "").Replace("]", "").Split(',').Length ?? 0;
  124. return;
  125. }
  126. if (funcName == "Match")
  127. {
  128. // 严格校验参数数量
  129. if (args.Parameters.Length != 2)
  130. {
  131. throw new ArgumentException("Match 必须传入 2 个参数:字符串、正则表达式");
  132. }
  133. // 安全获取参数值(避免 null)
  134. var str = args.Parameters[0].Evaluate()?.ToString() ?? string.Empty;
  135. var prefix = args.Parameters[1].Evaluate()?.ToString() ?? string.Empty;
  136. // 执行原生 StartsWith
  137. args.Result = Regex.IsMatch(str, prefix);
  138. return;
  139. }
  140. // 未找到函数时明确报错
  141. throw new ArgumentException($"未定义函数:{funcName}");
  142. }
  143. }