using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Elight.Utility.Extensions { /// /// /// /// Author:mxg /// CreatedTimed:2022-05-13 06:00 PM public static class StringExtension { /// /// 判断字符串是否为Null、空 /// /// /// public static bool IsNull(this string? s) => string.IsNullOrWhiteSpace(s); /// /// 判断字符串是否不为Null、空 /// /// /// public static bool NotNull(this string? s) => !string.IsNullOrWhiteSpace(s); /// /// /// /// /// public static bool IsNotEmptyOrNull(this object? thisValue) { var val = thisValue as string; return val != "" && val != "undefined" && val != "null"; } /// /// 与字符串进行比较,忽略大小写 /// /// /// /// public static bool EqualsIgnoreCase(this string s, string? value) => s.Equals(value, StringComparison.OrdinalIgnoreCase); /// /// 首字母转小写 /// /// /// public static string FirstCharToLower(this string s) { if (string.IsNullOrEmpty(s)) return s; string str = string.Concat(s.First().ToString().ToLower(), s.AsSpan(1)); return str; } /// /// 首字母转大写 /// /// /// public static string FirstCharToUpper(this string s) { if (string.IsNullOrEmpty(s)) return s; string str = string.Concat(s.First().ToString().ToUpper(), s.AsSpan(1)); return str; } /// /// 转为Base64,UTF-8格式 /// /// /// public static string ToBase64(this string s) => s.ToBase64(Encoding.UTF8); /// /// 转为Base64 /// /// /// 编码 /// public static string ToBase64(this string s, Encoding encoding) { if (s.IsNull()) return string.Empty; var bytes = encoding.GetBytes(s); if (bytes == null) return null; else return Convert.ToBase64String(bytes); } /// /// /// /// /// public static string ToPath(this string s) => s.IsNull() ? string.Empty : s.Replace(@"\", "/"); /// /// /// /// /// /// public static string Format(this string str, object obj) { if (str.IsNull()) return str; string s = str; if (obj.GetType().Name == "JObject") { foreach (var item in (Newtonsoft.Json.Linq.JObject)obj) { var k = item.Key.ToString(); string? v = item.Value?.ToString(); s = Regex.Replace(s, "\\{" + k + "\\}", v, RegexOptions.IgnoreCase); } } else { foreach (System.Reflection.PropertyInfo p in obj.GetType().GetProperties()) { var xx = p.Name; var yy = p.GetValue(obj)?.ToString(); s = Regex.Replace(s, "\\{" + xx + "\\}", yy, RegexOptions.IgnoreCase); } } return s; } #region IsXXXX /// /// /// /// /// /// public static bool GetGuid(this string guid, out Guid outId) => Guid.TryParse(guid, out outId); /// /// /// /// /// public static bool IsGuid(this string guid) => GetGuid(guid, out _); /// /// /// /// /// public static bool IsInt(this object? obj) { if (obj == null) return false; bool result = Int32.TryParse(obj.ToString(), out int number); return result; } /// /// /// /// /// public static bool IsDate(this object? str) => IsDate(str, out _); /// /// /// /// /// /// public static bool IsDate(this object? str, out DateTime dateTime) { dateTime = DateTime.Now; if (str == null || str.ToString() == "") return false; return DateTime.TryParse(str.ToString(), out dateTime); } /// /// 根据传入格式判断是否为小数 /// /// /// 18,5 /// public static bool IsNumber(this string str, string? formatString) { if (string.IsNullOrEmpty(str)) return false; int precision = 32; int scale = 5; try { if (string.IsNullOrEmpty(formatString)) { precision = 10; scale = 2; } else { string[] numbers = formatString.Split(','); precision = Convert.ToInt32(numbers[0]); scale = numbers.Length == 0 ? 2 : Convert.ToInt32(numbers[1]); } } catch { // ignored } return IsNumber(str, precision, scale); } /// /// 判断一个字符串是否为合法数字(指定整数位数和小数位数) /// /// 字符串 /// 整数位数 /// 小数位数 /// public static bool IsNumber(this string str, int precision, int scale) { if ((precision == 0) && (scale == 0)) return false; string pattern = @"(^\d{1," + precision + "}"; if (scale > 0) pattern += @"\.\d{0," + scale + "}$)|" + pattern; pattern += "$)"; return Regex.IsMatch(str, pattern); } #endregion IsXXXX // // Summary: // Concatenates the members of a constructed System.Collections.Generic.IEnumerable`1 // collection of type System.String, using the specified separator between each // member. This is a shortcut for string.Join(...) // // Parameters: // source: // A collection that contains the strings to concatenate. // // separator: // The string to use as a separator. separator is included in the returned string // only if values has more than one element. // // Returns: // A string that consists of the members of values delimited by the separator string. // If values has no members, the method returns System.String.Empty. public static string? JoinAsString(this IEnumerable source, string separator) => string.Join(separator, source); // // Summary: // Concatenates the members of a collection, using the specified separator between // each member. This is a shortcut for string.Join(...) // // Parameters: // source: // A collection that contains the objects to concatenate. // // separator: // The string to use as a separator. separator is included in the returned string // only if values has more than one element. // // Type parameters: // T: // The type of the members of values. // // Returns: // A string that consists of the members of values delimited by the separator string. // If values has no members, the method returns System.String.Empty. public static string JoinAsString(this IEnumerable source, string separator) => string.Join(separator, source); /// /// A string extension method that query if '@this' is null or empty. /// /// The @this to act on. /// true if null or empty, false if not. public static bool IsNullOrEmpty(this string @this) => string.IsNullOrEmpty(@this); /// /// A string extension method that query if '@this' is not null and not empty. /// /// The @this to act on. /// false if null or empty, true if not. public static bool IsNotNullOrEmpty(this string? @this) => !string.IsNullOrEmpty(@this); /// /// A string extension method that query if '@this' is null or whiteSpace. /// /// The @this to act on. /// true if null or whiteSpace, false if not. public static bool IsNullOrWhiteSpace(this string? @this) => string.IsNullOrWhiteSpace(@this); /// /// A string extension method that query if '@this' is not null and not whiteSpace. /// /// The @this to act on. /// false if null or whiteSpace, true if not. public static bool IsNotNullOrWhiteSpace(this string? @this) => !string.IsNullOrWhiteSpace(@this); /// /// Concatenates the elements of an object array, using the specified separator between each element. /// /// /// The string to use as a separator. is included in the returned string only if has more /// than one element. /// /// An array that contains the elements to concatenate. /// /// A string that consists of the elements of delimited by the string. If is an empty array, the method /// returns . /// public static string Join([NotNull] this string separator, IEnumerable values) => string.Join(separator, values); /// /// Indicates whether the specified regular expression finds a match in the specified input string. /// /// The string to search for a match. /// The regular expression pattern to match. /// true if the regular expression finds a match; otherwise, false. public static bool IsMatch([NotNull] this string input, string pattern) => Regex.IsMatch(input, pattern); /// /// Indicates whether the specified regular expression finds a match in the specified input string, using the /// specified matching options. /// /// The string to search for a match. /// The regular expression pattern to match. /// A bitwise combination of the enumeration values that provide options for matching. /// true if the regular expression finds a match; otherwise, false. public static bool IsMatch([NotNull] this string input, string pattern, RegexOptions options) => Regex.IsMatch(input, pattern, options); /// An IEnumerable<string> extension method that concatenates the given this. /// The @this to act on. /// A string. public static string Concatenate([NotNull] this IEnumerable @this) { var sb = new StringBuilder(); foreach (var s in @this) { sb.Append(s); } return sb.ToString(); } /// An IEnumerable<T> extension method that concatenates. /// Generic type parameter. /// The source to act on. /// The function. /// A string. public static string Concatenate([NotNull] this IEnumerable source, Func func) { var sb = new StringBuilder(); foreach (var item in source) { sb.Append(func(item)); } return sb.ToString(); } /// /// A string extension method that query if this object contains the given value. /// /// The @this to act on. /// The value. /// true if the value is in the string, false if not. public static bool Contains([NotNull] this string @this, string value) => @this.IndexOf(value, StringComparison.Ordinal) != -1; /// /// A string extension method that query if this object contains the given value. /// /// The @this to act on. /// The value. /// Type of the comparison. /// true if the value is in the string, false if not. public static bool Contains([NotNull] this string @this, string value, StringComparison comparisonType) => @this.IndexOf(value, comparisonType) != -1; /// /// A string extension method that extracts this object. /// /// The @this to act on. /// The predicate. /// A string. public static string Extract([NotNull] this string @this, Func predicate) => new string(@this.ToCharArray().Where(predicate).ToArray()); /// /// A string extension method that removes the letter. /// /// The @this to act on. /// The predicate. /// A string. public static string RemoveWhere([NotNull] this string @this, Func predicate) => new string(@this.ToCharArray().Where(x => !predicate(x)).ToArray()); /// /// Replaces the format item in a specified String with the text equivalent of the value of a corresponding /// Object instance in a specified array. /// /// A String containing zero or more format items. /// An Object array containing zero or more objects to format. /// /// A copy of format in which the format items have been replaced by the String equivalent of the corresponding /// instances of Object in args. /// public static string FormatWith([NotNull] this string @this, params object[] values) => string.Format(@this, values); /// /// A string extension method that query if '@this' satisfy the specified pattern. /// /// The @this to act on. /// The pattern to use. Use '*' as wildcard string. /// true if '@this' satisfy the specified pattern, false if not. public static bool IsLike([NotNull] this string @this, string pattern) { // Turn the pattern into regex pattern, and match the whole string with ^$ var regexPattern = "^" + Regex.Escape(pattern) + "$"; // Escape special character ?, #, *, [], and [!] regexPattern = regexPattern.Replace(@"\[!", "[^") .Replace(@"\[", "[") .Replace(@"\]", "]") .Replace(@"\?", ".") .Replace(@"\*", ".*") .Replace(@"\#", @"\d"); return Regex.IsMatch(@this, regexPattern); } /// /// SafeSubstring /// /// /// /// public static string SafeSubstring([NotNull] this string @this, int startIndex) { if (startIndex < 0 || startIndex > @this.Length) { return string.Empty; } return @this[startIndex..]; } /// /// SafeSubstring /// /// /// /// /// public static string SafeSubstring([NotNull] this string str, int startIndex, int length) { if (startIndex < 0 || startIndex >= str.Length || length < 0) { return string.Empty; } return str.Substring(startIndex, Math.Min(str.Length - startIndex, length)); } /// /// Sub, not only substring but support for negative numbers /// /// string to be handled /// startIndex to substract /// substring public static string Sub([NotNull] this string @this, int startIndex) { if (startIndex >= 0) { return @this.SafeSubstring(startIndex); } if (Math.Abs(startIndex) > @this.Length) { return string.Empty; } return @this[(@this.Length + startIndex)..]; } /// /// A string extension method that repeats the string a specified number of times. /// /// The @this to act on. /// Number of repeats. /// The repeated string. public static string Repeat([NotNull] this string @this, int repeatCount) { if (@this.Length == 1) { return new string(@this[0], repeatCount); } var sb = new StringBuilder(repeatCount * @this.Length); while (repeatCount-- > 0) { sb.Append(@this); } return sb.ToString(); } /// /// A string extension method that reverses the given string. /// /// The @this to act on. /// The string reversed. public static string Reverse([NotNull] this string @this) { if (@this.Length <= 1) { return @this; } var chars = @this.ToCharArray(); Array.Reverse(chars); return new string(chars); } /// /// Returns a String array containing the substrings in this string that are delimited by elements of a specified /// String array. A parameter specifies whether to return empty array elements. /// /// The @this to act on. /// A string that delimit the substrings in this string. /// /// (Optional) Specify RemoveEmptyEntries to omit empty array elements from the array returned, /// or None to include empty array elements in the array returned. /// /// /// An array whose elements contain the substrings in this string that are delimited by the separator. /// public static string[] Split([NotNull] this string @this, string separator, StringSplitOptions option = StringSplitOptions.None) => @this.Split(new[] { separator }, option); /// /// A string extension method that converts the @this to a byte array. /// /// The @this to act on. /// @this as a byte[]. public static byte[] ToByteArray([NotNull] this string @this) => Encoding.UTF8.GetBytes(@this); /// /// A string extension method that converts the @this to a byte array. /// /// The @this to act on. /// encoding /// @this as a byte[]. public static byte[] ToByteArray([NotNull] this string @this, Encoding encoding) => encoding.GetBytes(@this); public static byte[] GetBytes([NotNull] this string str) => str.GetBytes(Encoding.UTF8); public static byte[] GetBytes([NotNull] this string? str, Encoding encoding) => encoding.GetBytes(str); /// /// A string extension method that converts the @this to an enum. /// /// Generic type parameter. /// The @this to act on. /// @this as a T. public static T ToEnum([NotNull] this string @this) => (T)System.Enum.Parse(typeof(T), @this); /// /// A string extension method that converts the @this to a title case. /// /// The @this to act on. /// @this as a string. public static string ToTitleCase([NotNull] this string @this) => new CultureInfo("en-US").TextInfo.ToTitleCase(@this); /// /// A string extension method that converts the @this to a title case. /// /// The @this to act on. /// Information describing the culture. /// @this as a string. public static string ToTitleCase([NotNull] this string @this, CultureInfo cultureInfo) => cultureInfo.TextInfo.ToTitleCase(@this); /// /// A string extension method that truncates. /// /// The @this to act on. /// The maximum length. /// A string. public static string Truncate(this string @this, int maxLength) => @this.Truncate(maxLength, "..."); /// /// A string extension method that truncates. /// /// The @this to act on. /// The maximum length. /// The suffix. /// A string. public static string Truncate(this string @this, int maxLength, string suffix) { if (@this == null || @this.Length <= maxLength) { return @this; } return @this.Substring(0, maxLength - suffix.Length) + suffix; } /// /// string=>long /// /// /// public static long? ToLong(this string? @this) { bool status = long.TryParse(@this, out long result); if (status) return result; else return null; } #region 处理Windows和Linux 系统下文件路径 处理方法 /// /// 处理Windows和Linux 系统下文件路径 /// /// /// public static string GetRuntimeDirectory(this string path) { if (IsLinuxRunTime()) return GetLinuxDirectory(path); return IsWindowRunTime() ? GetWindowDirectory(path) : path; } public static bool IsWindowRunTime() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows); public static bool IsLinuxRunTime() => RuntimeInformation.IsOSPlatform(OSPlatform.Linux); private static string GetLinuxDirectory(string path) { var pathTemp = Path.Combine(path); return pathTemp.Replace("\\", "/"); } private static string GetWindowDirectory(string path) { var pathTemp = Path.Combine(path); return pathTemp.Replace("/", "\\"); } #endregion 处理Windows和Linux 系统下文件路径 处理方法 } }