using Newtonsoft.Json.Linq; using Serein.Library.Utils; using Serein.Library.Utils.SereinExpression.Resolver; using System; using System.Collections.Generic; using System.ComponentModel.Design; using System.Globalization; using System.Linq; using System.Reflection; namespace Serein.Library.Utils.SereinExpression { /// /// 字符串工具类 /// public static class StringHelper { /// /// Net低版本无法引入Skip函数,所以使用扩展方法代替 /// /// /// /// /// /// public static IEnumerable MySkip(this IEnumerable source, int count) { if (source == null) throw new ArgumentNullException(nameof(source)); int skipped = 0; foreach (var item in source) { if (skipped++ >= count) yield return item; } } /// /// 连接字符串数组的指定部分 /// /// /// /// /// /// /// /// public static string JoinStrings(string[] parts, int startIndex, int count, char separator) { if (parts == null) throw new ArgumentNullException(nameof(parts)); if (startIndex < 0 || startIndex >= parts.Length || count < 0 || startIndex + count > parts.Length) throw new ArgumentOutOfRangeException(); // 复制需要的部分到新的数组 string[] subArray = new string[count]; Array.Copy(parts, startIndex, subArray, 0, count); // 使用 string.Join 连接 return string.Join(separator.ToString(), subArray); } } /// /// 条件解析器(生成IL进行判断) /// 格式: data.[propertyName] [operator] [value] /// public class SereinConditionParser { /// /// 条件表达式 /// /// /// /// /// public static bool To(T data, string expression) { try { if (string.IsNullOrEmpty(expression)) { return false; } var parse = ConditionParse(data, expression); // 解析条件 var result = parse.Evaluate(data); // 执行判断 return result; } catch (Exception ex) { SereinEnv.WriteLine(InfoType.ERROR, ex.ToString()); throw; } } /// /// 解析条件 /// /// /// /// private static SereinConditionResolver ConditionParse(object data, string expression) { //ReadOnlySpan expSpan = expression.AsSpan(); if (expression[0] == '.') // 表达式前缀属于从上一个节点数据对象获取成员值 { return ParseObjectExpression(data, expression); // 对象表达式解析 } else { return ParseSimpleExpression(data, expression); // 简单表达式解析 } //bool ContainsArithmeticOperators(string expression) //{ // return expression.Contains('+') || expression.Contains('-') || expression.Contains('*') || expression.Contains('/'); //} } /// /// 获取计算表达式的部分 /// /// /// private static string GetArithmeticExpression(string part) { int startIndex = part.IndexOf('['); int endIndex = part.IndexOf(']'); if (startIndex >= 0 && endIndex > startIndex) { return part.Substring(startIndex + 1, endIndex - startIndex - 1); } return null; } /// /// 获取对象指定名称的成员 /// private static object GetMemberValue(object obj, string memberPath) { //string[] members = memberPath[1..].Split('.'); string[] members = memberPath.Substring(1).Split('.'); foreach (var member in members) { if (obj is null) return null; Type type = obj.GetType(); PropertyInfo propertyInfo = type.GetProperty(member); FieldInfo fieldInfo = type.GetField(member); if (propertyInfo != null) obj = propertyInfo.GetValue(obj); else if (fieldInfo != null) obj = fieldInfo.GetValue(obj); else throw new ArgumentException($"Member {member} not found in type {type.FullName}"); } return obj; } /// /// 解析对象表达式 /// private static SereinConditionResolver ParseObjectExpression(object data, string expression) { var parts = expression.Split(' '); string operatorStr = parts[0]; // 获取操作类型 string valueStr; //= string.Join(' ', parts, 1, parts.Length - 1); string memberPath; Type type; object targetObj; // 尝试获取指定类型 int typeStartIndex = expression.IndexOf('<'); int typeEndIndex = expression.IndexOf('>'); if (typeStartIndex + typeStartIndex == -2) { // 如果不需要转为指定类型 memberPath = operatorStr; targetObj = SerinExpressionEvaluator.Evaluate("@get " + operatorStr, data, out _); //targetObj = GetMemberValue(data, operatorStr); type = targetObj.GetType(); operatorStr = parts[1].ToLower(); // valueStr = string.Join(" ", parts.Skip(2)); } else { // 类型语法不正确 if (typeStartIndex >= typeEndIndex) { throw new ArgumentException("无效的表达式格式"); } memberPath = expression.Substring(0, typeStartIndex).Trim(); string typeStr = expression.Substring(typeStartIndex + 1, typeEndIndex - typeStartIndex - 1) .Trim().ToLower(); // 手动置顶的类型 // 对象取值表达式 parts = expression.Substring(typeEndIndex + 1).Trim().Split(' '); if (parts.Length == 3) { operatorStr = parts[1].ToLower(); // 操作类型 valueStr = string.Join(" ", parts.Skip(2)); // 表达式值 } else { operatorStr = parts[0].ToLower(); // 操作类型 valueStr = string.Join(" ", parts.Skip(1)); // 表达式值 } type = typeStr.ToTypeOfString(); if (string.IsNullOrWhiteSpace(memberPath)) { targetObj = Convert.ChangeType(data, type); } else { targetObj = GetMemberValue(data, memberPath);// 获取对象成员,作为表达式的目标对象 } } #region 解析类型 int if (type.IsValueType) { //return GetValueResolver(type, valueStr, operatorStr, parts); } if (type == typeof(int)) { var op = ParseValueTypeOperator(operatorStr); if (op == ValueTypeConditionResolver.Operator.InRange || op == ValueTypeConditionResolver.Operator.OutOfRange) { var temp = valueStr.Split('-'); if (temp.Length < 2) throw new ArgumentException($"范围无效:{valueStr}。"); int rangeStart = int.Parse(temp[0], CultureInfo.InvariantCulture); int rangeEnd = int.Parse(temp[1], CultureInfo.InvariantCulture); return new MemberConditionResolver { Op = op, RangeStart = rangeStart, RangeEnd = rangeEnd, TargetObj = targetObj, ArithmeticExpression = GetArithmeticExpression(parts[0]), }; } else { int value = int.Parse(valueStr, CultureInfo.InvariantCulture); return new MemberConditionResolver { TargetObj = targetObj, //MemberPath = memberPath, Op = ParseValueTypeOperator(operatorStr), Value = value, ArithmeticExpression = GetArithmeticExpression(parts[0]) }; } } #endregion #region 解析类型 double else if (type == typeof(double)) { double value = double.Parse(valueStr, CultureInfo.InvariantCulture); return new MemberConditionResolver { //MemberPath = memberPath, TargetObj = targetObj, Op = ParseValueTypeOperator(operatorStr), Value = value, ArithmeticExpression = GetArithmeticExpression(parts[0]) }; } #endregion #region 解析类型 bool else if (type == typeof(bool)) { bool targetData = false; if (targetObj is bool tmp) { targetData = tmp; } else { targetObj = bool.Parse(targetObj.ToString()); } return new BoolConditionResolver { //Value = bool.Parse(targetObj.ToString()), Value = bool.Parse(valueStr), Data = targetData, Op = BoolConditionResolver.Operator.Is }; } #endregion #region 解析类型 string else if (type == typeof(string)) { return new MemberStringConditionResolver { MemberPath = memberPath, Op = ParseStringOperator(operatorStr), Value = valueStr }; } #endregion throw new NotSupportedException($"Type {type} is not supported."); } /// /// 条件表达式解析 /// /// /// /// /// /// private static SereinConditionResolver ParseSimpleExpression(object data, string expression) { var parts = expression.Split(' '); if (parts.Length < 2) throw new ArgumentException("无效的表达式格式。"); string operatorStr; string valueStr; // 尝试获取指定类型 var hasType = SereinExpressionExtension.TryGetType(expression, out _, out var type); if (!hasType) { // 如果不需要转为指定类型 operatorStr = parts[0]; #if NET8_0_OR_GREATER valueStr = string.Join(' ', parts, 1, parts.Length - 1); #elif NET462_OR_GREATER valueStr = StringHelper.JoinStrings(parts, 1, parts.Length - 1, ' '); #endif type = data.GetType(); } else {//string typeStr = parts[0]; int endIndex = expression.IndexOf('>'); parts = expression.Substring(endIndex + 1).Split(' '); operatorStr = parts[0].ToLower(); // 操作类型 valueStr = string.Join(" ", parts.Skip(1)); // 表达式值 } if (type == typeof(bool)) { bool value = bool.Parse(valueStr); return new BoolConditionResolver { Op = ParseBoolOperator(operatorStr), Value = value, }; } else if (type.IsValueType) { return GetValueResolver(type, valueStr, operatorStr, parts); } else if (type == typeof(string)) { return new StringConditionResolver { Op = ParseStringOperator(operatorStr), Value = valueStr }; } throw new NotSupportedException($"Type {type} is not supported."); } public static SereinConditionResolver GetValueResolver(Type valueType, string valueStr, string operatorStr, string[] parts)// where T : struct, IComparable { SereinConditionResolver resolver; if (valueType == typeof(float)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(decimal)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(double)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(sbyte)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(byte)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(short)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(ushort)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(int)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(uint)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(long)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(ulong)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } #if NET8_0_OR_GREATER else if (valueType == typeof(nint)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } else if (valueType == typeof(nuint)) { resolver = GetValueResolver(valueStr, operatorStr, parts); } #endif else { throw new ArgumentException("非预期值类型"); } return resolver; } private static ValueTypeConditionResolver GetValueResolver(string valueStr, string operatorStr, string[] parts) where T :struct, IComparable { var op = ParseValueTypeOperator(operatorStr); if (op == ValueTypeConditionResolver.Operator.InRange || op == ValueTypeConditionResolver.Operator.OutOfRange) { var temp = valueStr.Split('-'); var leftNum = string.Empty; var rightNum = string.Empty; if (temp.Length < 2 || temp.Length > 4) { throw new ArgumentException($"范围无效:{valueStr}。"); } else if (temp.Length == 2) { leftNum = temp[0]; rightNum = temp[1]; } else if (temp.Length == 3) { if (string.IsNullOrEmpty(temp[0]) && !string.IsNullOrEmpty(temp[1]) && !string.IsNullOrEmpty(temp[2])) { leftNum = "-" + temp[1]; rightNum = temp[2]; } else { throw new ArgumentException($"范围无效:{valueStr}。"); } } else if (temp.Length == 4) { if (string.IsNullOrEmpty(temp[0]) && !string.IsNullOrEmpty(temp[1]) && string.IsNullOrEmpty(temp[2]) && !string.IsNullOrEmpty(temp[3])) { leftNum = "-" + temp[1]; rightNum = temp[3]; } else { throw new ArgumentException($"范围无效:{valueStr}。"); } } return new ValueTypeConditionResolver { Op = op, RangeStart = leftNum.ToValueData(), RangeEnd = rightNum.ToValueData(), ArithmeticExpression = GetArithmeticExpression(parts[0]), }; } else { return new ValueTypeConditionResolver { Op = op, Value = valueStr.ToValueData(), ArithmeticExpression = GetArithmeticExpression(parts[0]) }; } } /// /// 数值操作类型 /// /// /// /// /// private static ValueTypeConditionResolver.Operator ParseValueTypeOperator(string operatorStr) where T : struct, IComparable { if (operatorStr == ">") { return ValueTypeConditionResolver.Operator.GreaterThan; } else if (operatorStr == "<") { return ValueTypeConditionResolver.Operator.LessThan; } else if (operatorStr == "==") { return ValueTypeConditionResolver.Operator.Equal; } else if (operatorStr == ">=" || operatorStr == "≥") { return ValueTypeConditionResolver.Operator.GreaterThanOrEqual; } else if (operatorStr == "<=" || operatorStr == "≤") { return ValueTypeConditionResolver.Operator.LessThanOrEqual; } else if (operatorStr == "in") { return ValueTypeConditionResolver.Operator.InRange; } else if (operatorStr == "!in") { return ValueTypeConditionResolver.Operator.OutOfRange; } else { throw new ArgumentException($"Invalid operator {operatorStr} for value type."); } } /// /// 布尔操作类型 /// /// /// /// private static BoolConditionResolver.Operator ParseBoolOperator(string operatorStr) { if (operatorStr == "is" || operatorStr == "==" || operatorStr == "equals") { return BoolConditionResolver.Operator.Is; } else { throw new ArgumentException($"Invalid operator {operatorStr} for bool type."); } } /// /// 字符串操作类型 /// /// /// /// private static StringConditionResolver.Operator ParseStringOperator(string operatorStr) { operatorStr = operatorStr.ToLower(); if (operatorStr == "c" || operatorStr == "contains") { return StringConditionResolver.Operator.Contains; } else if (operatorStr == "nc" || operatorStr == "doesnotcontain") { return StringConditionResolver.Operator.DoesNotContain; } else if (operatorStr == "sw" || operatorStr == "startswith") { return StringConditionResolver.Operator.StartsWith; } else if (operatorStr == "ew" || operatorStr == "endswith") { return StringConditionResolver.Operator.EndsWith; } else if (operatorStr == "==" || operatorStr == "equals") { return StringConditionResolver.Operator.Equal; } else if (operatorStr == "!=" || operatorStr == "notequals") { return StringConditionResolver.Operator.NotEqual; } else { throw new ArgumentException($"Invalid operator {operatorStr} for string type."); } } } } //public static T ValueParse(object value) where T : struct, IComparable //{ // return (T)ValueParse(typeof(T), value); //} //public static object ValueParse(Type type, object value) //{ // string? valueStr = value.ToString(); // if (string.IsNullOrEmpty(valueStr)) // { // throw new ArgumentException("value is null"); // } // object result = type switch // { // Type t when t.IsEnum => Enum.Parse(type, valueStr), // Type t when t == typeof(bool) => bool.Parse(valueStr), // Type t when t == typeof(float) => float.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(decimal) => decimal.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(double) => double.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(sbyte) => sbyte.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(byte) => byte.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(short) => short.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(ushort) => ushort.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(int) => int.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(uint) => uint.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(long) => long.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(ulong) => ulong.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(nint) => nint.Parse(valueStr, CultureInfo.InvariantCulture), // Type t when t == typeof(nuint) => nuint.Parse(valueStr, CultureInfo.InvariantCulture), // _ => throw new ArgumentException("非预期值类型") // }; // return result; //}