24小时一体机服务
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

655 lines
26 KiB

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
{
/// <summary>
///
/// </summary>
/// Author:mxg
/// CreatedTimed:2022-05-13 06:00 PM
public static class StringExtension
{
/// <summary>
/// 判断字符串是否为Null、空
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static bool IsNull(this string? s) => string.IsNullOrWhiteSpace(s);
/// <summary>
/// 判断字符串是否不为Null、空
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static bool NotNull(this string? s) => !string.IsNullOrWhiteSpace(s);
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <returns></returns>
public static bool IsNotEmptyOrNull(this object? thisValue)
{
var val = thisValue as string;
return val != "" && val != "undefined" && val != "null";
}
/// <summary>
/// 与字符串进行比较,忽略大小写
/// </summary>
/// <param name="s"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool EqualsIgnoreCase(this string s, string? value) => s.Equals(value, StringComparison.OrdinalIgnoreCase);
/// <summary>
/// 首字母转小写
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 首字母转大写
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 转为Base64,UTF-8格式
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string ToBase64(this string s) => s.ToBase64(Encoding.UTF8);
/// <summary>
/// 转为Base64
/// </summary>
/// <param name="s"></param>
/// <param name="encoding">编码</param>
/// <returns></returns>
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);
}
/// <summary>
///
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string ToPath(this string s) => s.IsNull() ? string.Empty : s.Replace(@"\", "/");
/// <summary>
///
/// </summary>
/// <param name="str"></param>
/// <param name="obj"></param>
/// <returns></returns>
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
/// <summary>
///
/// </summary>
/// <param name="guid"></param>
/// <param name="outId"></param>
/// <returns></returns>
public static bool GetGuid(this string guid, out Guid outId) => Guid.TryParse(guid, out outId);
/// <summary>
///
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
public static bool IsGuid(this string guid) => GetGuid(guid, out _);
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static bool IsInt(this object? obj)
{
if (obj == null) return false;
bool result = Int32.TryParse(obj.ToString(), out int number);
return result;
}
/// <summary>
///
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static bool IsDate(this object? str) => IsDate(str, out _);
/// <summary>
///
/// </summary>
/// <param name="str"></param>
/// <param name="dateTime"></param>
/// <returns></returns>
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);
}
/// <summary>
/// 根据传入格式判断是否为小数
/// </summary>
/// <param name="str"></param>
/// <param name="formatString">18,5</param>
/// <returns></returns>
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);
}
/// <summary>
/// 判断一个字符串是否为合法数字(指定整数位数和小数位数)
/// </summary>
/// <param name="str">字符串</param>
/// <param name="precision">整数位数</param>
/// <param name="scale">小数位数</param>
/// <returns></returns>
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<string> 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<T>(this IEnumerable<T> source, string separator) => string.Join(separator, source);
/// <summary>
/// A string extension method that query if '@this' is null or empty.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <returns>true if null or empty, false if not.</returns>
public static bool IsNullOrEmpty(this string @this) => string.IsNullOrEmpty(@this);
/// <summary>
/// A string extension method that query if '@this' is not null and not empty.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <returns>false if null or empty, true if not.</returns>
public static bool IsNotNullOrEmpty(this string? @this) => !string.IsNullOrEmpty(@this);
/// <summary>
/// A string extension method that query if '@this' is null or whiteSpace.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <returns>true if null or whiteSpace, false if not.</returns>
public static bool IsNullOrWhiteSpace(this string? @this) => string.IsNullOrWhiteSpace(@this);
/// <summary>
/// A string extension method that query if '@this' is not null and not whiteSpace.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <returns>false if null or whiteSpace, true if not.</returns>
public static bool IsNotNullOrWhiteSpace(this string? @this) => !string.IsNullOrWhiteSpace(@this);
/// <summary>
/// Concatenates the elements of an object array, using the specified separator between each element.
/// </summary>
/// <param name="separator">
/// The string to use as a separator. is included in the returned string only if has more
/// than one element.
/// </param>
/// <param name="values">An array that contains the elements to concatenate.</param>
/// <returns>
/// A string that consists of the elements of delimited by the string. If is an empty array, the method
/// returns .
/// </returns>
public static string Join<T>([NotNull] this string separator, IEnumerable<T> values) => string.Join(separator, values);
/// <summary>
/// Indicates whether the specified regular expression finds a match in the specified input string.
/// </summary>
/// <param name="input">The string to search for a match.</param>
/// <param name="pattern">The regular expression pattern to match.</param>
/// <returns>true if the regular expression finds a match; otherwise, false.</returns>
public static bool IsMatch([NotNull] this string input, string pattern) => Regex.IsMatch(input, pattern);
/// <summary>
/// Indicates whether the specified regular expression finds a match in the specified input string, using the
/// specified matching options.
/// </summary>
/// <param name="input">The string to search for a match.</param>
/// <param name="pattern">The regular expression pattern to match.</param>
/// <param name="options">A bitwise combination of the enumeration values that provide options for matching.</param>
/// <returns>true if the regular expression finds a match; otherwise, false.</returns>
public static bool IsMatch([NotNull] this string input, string pattern, RegexOptions options) => Regex.IsMatch(input, pattern, options);
/// <summary>An IEnumerable&lt;string&gt; extension method that concatenates the given this.</summary>
/// <param name="this">The @this to act on.</param>
/// <returns>A string.</returns>
public static string Concatenate([NotNull] this IEnumerable<string> @this)
{
var sb = new StringBuilder();
foreach (var s in @this)
{
sb.Append(s);
}
return sb.ToString();
}
/// <summary>An IEnumerable&lt;T&gt; extension method that concatenates.</summary>
/// <typeparam name="T">Generic type parameter.</typeparam>
/// <param name="source">The source to act on.</param>
/// <param name="func">The function.</param>
/// <returns>A string.</returns>
public static string Concatenate<T>([NotNull] this IEnumerable<T> source, Func<T, string> func)
{
var sb = new StringBuilder();
foreach (var item in source)
{
sb.Append(func(item));
}
return sb.ToString();
}
/// <summary>
/// A string extension method that query if this object contains the given value.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="value">The value.</param>
/// <returns>true if the value is in the string, false if not.</returns>
public static bool Contains([NotNull] this string @this, string value) => @this.IndexOf(value, StringComparison.Ordinal) != -1;
/// <summary>
/// A string extension method that query if this object contains the given value.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="value">The value.</param>
/// <param name="comparisonType">Type of the comparison.</param>
/// <returns>true if the value is in the string, false if not.</returns>
public static bool Contains([NotNull] this string @this, string value, StringComparison comparisonType) => @this.IndexOf(value, comparisonType) != -1;
/// <summary>
/// A string extension method that extracts this object.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="predicate">The predicate.</param>
/// <returns>A string.</returns>
public static string Extract([NotNull] this string @this, Func<char, bool> predicate) => new string(@this.ToCharArray().Where(predicate).ToArray());
/// <summary>
/// A string extension method that removes the letter.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="predicate">The predicate.</param>
/// <returns>A string.</returns>
public static string RemoveWhere([NotNull] this string @this, Func<char, bool> predicate) => new string(@this.ToCharArray().Where(x => !predicate(x)).ToArray());
/// <summary>
/// Replaces the format item in a specified String with the text equivalent of the value of a corresponding
/// Object instance in a specified array.
/// </summary>
/// <param name="this">A String containing zero or more format items.</param>
/// <param name="values">An Object array containing zero or more objects to format.</param>
/// <returns>
/// A copy of format in which the format items have been replaced by the String equivalent of the corresponding
/// instances of Object in args.
/// </returns>
public static string FormatWith([NotNull] this string @this, params object[] values) => string.Format(@this, values);
/// <summary>
/// A string extension method that query if '@this' satisfy the specified pattern.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="pattern">The pattern to use. Use '*' as wildcard string.</param>
/// <returns>true if '@this' satisfy the specified pattern, false if not.</returns>
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);
}
/// <summary>
/// SafeSubstring
/// </summary>
/// <param name="this"></param>
/// <param name="startIndex"></param>
/// <returns></returns>
public static string SafeSubstring([NotNull] this string @this, int startIndex)
{
if (startIndex < 0 || startIndex > @this.Length)
{
return string.Empty;
}
return @this[startIndex..];
}
/// <summary>
/// SafeSubstring
/// </summary>
/// <param name="str"></param>
/// <param name="startIndex"></param>
/// <param name="length"></param>
/// <returns></returns>
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));
}
/// <summary>
/// Sub, not only substring but support for negative numbers
/// </summary>
/// <param name="this">string to be handled</param>
/// <param name="startIndex">startIndex to substract</param>
/// <returns>substring</returns>
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)..];
}
/// <summary>
/// A string extension method that repeats the string a specified number of times.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="repeatCount">Number of repeats.</param>
/// <returns>The repeated string.</returns>
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();
}
/// <summary>
/// A string extension method that reverses the given string.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <returns>The string reversed.</returns>
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);
}
/// <summary>
/// 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.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="separator">A string that delimit the substrings in this string.</param>
/// <param name="option">
/// (Optional) Specify RemoveEmptyEntries to omit empty array elements from the array returned,
/// or None to include empty array elements in the array returned.
/// </param>
/// <returns>
/// An array whose elements contain the substrings in this string that are delimited by the separator.
/// </returns>
public static string[] Split([NotNull] this string @this, string separator, StringSplitOptions option = StringSplitOptions.None) => @this.Split(new[] { separator }, option);
/// <summary>
/// A string extension method that converts the @this to a byte array.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <returns>@this as a byte[].</returns>
public static byte[] ToByteArray([NotNull] this string @this) => Encoding.UTF8.GetBytes(@this);
/// <summary>
/// A string extension method that converts the @this to a byte array.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="encoding">encoding</param>
/// <returns>@this as a byte[].</returns>
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);
/// <summary>
/// A string extension method that converts the @this to an enum.
/// </summary>
/// <typeparam name="T">Generic type parameter.</typeparam>
/// <param name="this">The @this to act on.</param>
/// <returns>@this as a T.</returns>
public static T ToEnum<T>([NotNull] this string @this) => (T)System.Enum.Parse(typeof(T), @this);
/// <summary>
/// A string extension method that converts the @this to a title case.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <returns>@this as a string.</returns>
public static string ToTitleCase([NotNull] this string @this) => new CultureInfo("en-US").TextInfo.ToTitleCase(@this);
/// <summary>
/// A string extension method that converts the @this to a title case.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="cultureInfo">Information describing the culture.</param>
/// <returns>@this as a string.</returns>
public static string ToTitleCase([NotNull] this string @this, CultureInfo cultureInfo) => cultureInfo.TextInfo.ToTitleCase(@this);
/// <summary>
/// A string extension method that truncates.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="maxLength">The maximum length.</param>
/// <returns>A string.</returns>
public static string Truncate(this string @this, int maxLength) => @this.Truncate(maxLength, "...");
/// <summary>
/// A string extension method that truncates.
/// </summary>
/// <param name="this">The @this to act on.</param>
/// <param name="maxLength">The maximum length.</param>
/// <param name="suffix">The suffix.</param>
/// <returns>A string.</returns>
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;
}
/// <summary>
/// string=>long
/// </summary>
/// <param name="txt"></param>
/// <returns></returns>
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 系统下文件路径 处理方法
/// <summary>
/// 处理Windows和Linux 系统下文件路径
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
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 系统下文件路径 处理方法
}
}