using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; using Newtonsoft.Json; namespace Masuit.Tools { /// /// 扩展方法 /// public static class Extensions { #region SyncForEach /// /// 遍历数组 /// /// /// 回调方法 public static void ForEach(this object[] objs, Action action) { foreach (var o in objs) { action(o); } } /// /// 遍历IEnumerable /// /// /// 回调方法 public static void ForEach(this IEnumerable objs, Action action) { foreach (var o in objs) { action(o); } } /// /// 遍历集合 /// /// /// 回调方法 public static void ForEach(this IList objs, Action action) { foreach (var o in objs) { action(o); } } /// /// 遍历数组 /// /// /// 回调方法 /// public static void ForEach(this T[] objs, Action action) { foreach (var o in objs) { action(o); } } /// /// 遍历IEnumerable /// /// /// 回调方法 /// public static void ForEach(this IEnumerable objs, Action action) { foreach (var o in objs) { action(o); } } /// /// 遍历List /// /// /// 回调方法 /// public static void ForEach(this IList objs, Action action) { foreach (var o in objs) { action(o); } } /// /// 遍历数组并返回一个新的List /// /// /// 回调方法 /// public static IEnumerable ForEach(this object[] objs, Func action) { foreach (var o in objs) { yield return action(o); } } /// /// 遍历IEnumerable并返回一个新的List /// /// /// 回调方法 /// /// public static IEnumerable ForEach(this IEnumerable objs, Func action) { foreach (var o in objs) { yield return action(o); } } /// /// 遍历List并返回一个新的List /// /// /// 回调方法 /// /// public static IEnumerable ForEach(this IList objs, Func action) { foreach (var o in objs) { yield return action(o); } } /// /// 遍历数组并返回一个新的List /// /// /// 回调方法 /// /// public static IEnumerable ForEach(this T[] objs, Func action) { foreach (var o in objs) { yield return action(o); } } /// /// 遍历IEnumerable并返回一个新的List /// /// /// 回调方法 /// /// public static IEnumerable ForEach(this IEnumerable objs, Func action) { foreach (var o in objs) { yield return action(o); } } /// /// 遍历List并返回一个新的List /// /// /// 回调方法 /// /// public static IEnumerable ForEach(this IList objs, Func action) { foreach (var o in objs) { yield return action(o); } } #endregion #region AsyncForEach /// /// 遍历数组 /// /// /// 回调方法 public static async void ForEachAsync(this object[] objs, Action action) { await Task.Run(() => { Parallel.ForEach(objs, action); }); } /// /// 遍历数组 /// /// /// 回调方法 /// public static async void ForEachAsync(this T[] objs, Action action) { await Task.Run(() => { Parallel.ForEach(objs, action); }); } /// /// 遍历IEnumerable /// /// /// 回调方法 /// public static async void ForEachAsync(this IEnumerable objs, Action action) { await Task.Run(() => { Parallel.ForEach(objs, action); }); } /// /// 遍历List /// /// /// 回调方法 /// public static async void ForEachAsync(this IList objs, Action action) { await Task.Run(() => { Parallel.ForEach(objs, action); }); } #endregion #region Map /// /// 映射到目标类型(浅克隆) /// /// 源 /// 目标类型 /// 目标类型 public static TDestination MapTo(this object source) where TDestination : new() { TDestination dest = new TDestination(); dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source)); }); return dest; } /// /// 映射到目标类型(浅克隆) /// /// 源 /// 目标类型 /// 目标类型 public static async Task MapToAsync(this object source) where TDestination : new() { return await Task.Run(() => { TDestination dest = new TDestination(); dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source)); }); return dest; }); } /// /// 映射到目标类型(深克隆) /// /// 源 /// 目标类型 /// 目标类型 public static TDestination Map(this object source) where TDestination : new() => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(source)); /// /// 映射到目标类型(深克隆) /// /// 源 /// 目标类型 /// 目标类型 public static async Task MapAsync(this object source) where TDestination : new() => await Task.Run(() => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(source))); /// /// 复制一个新的对象 /// /// /// /// public static T Copy(this T source) where T : new() { T dest = new T(); dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source)); }); return dest; } /// /// 复制到一个现有对象 /// /// /// 源对象 /// 目标对象 /// public static T CopyTo(this T source, T dest) where T : new() { dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source)); }); return dest; } /// /// 复制一个新的对象 /// /// /// /// public static async Task CopyAsync(this T source) where T : new() => await Task.Run(() => { T dest = new T(); dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source)); }); return dest; }); /// /// 映射到目标类型的集合 /// /// 源 /// 目标类型 /// 目标类型集合 public static IEnumerable ToList(this object[] source) where TDestination : new() { foreach (var o in source) { var dest = new TDestination(); dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); }); yield return dest; } } /// /// 映射到目标类型的集合 /// /// 源 /// 目标类型 /// 目标类型集合 public static async Task> ToListAsync(this object[] source) where TDestination : new() { return await Task.Run(() => { IList list = new List(); foreach (var o in source) { var dest = new TDestination(); dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); }); list.Add(dest); } return list; }); } /// /// 映射到目标类型的集合 /// /// 源 /// 目标类型 /// 目标类型集合 public static IEnumerable ToList(this IList source) where TDestination : new() { foreach (var o in source) { var dest = new TDestination(); dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); }); yield return dest; } } /// /// 映射到目标类型的集合 /// /// 源 /// 目标类型 /// 目标类型集合 public static async Task> ToListAsync(this IList source) where TDestination : new() { return await Task.Run(() => { IList list = new List(); foreach (var o in source) { var dest = new TDestination(); dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); }); list.Add(dest); } return list; }); } /// /// 映射到目标类型的集合 /// /// 源 /// 目标类型 /// 目标类型集合 public static IEnumerable ToList(this IEnumerable source) where TDestination : new() { foreach (var o in source) { var dest = new TDestination(); dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); }); yield return dest; } } /// /// 映射到目标类型的集合 /// /// 源 /// 目标类型 /// 目标类型集合 public static async Task> ToListAsync(this IEnumerable source) where TDestination : new() { return await Task.Run(() => { IList list = new List(); foreach (var o in source) { var dest = new TDestination(); dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); }); list.Add(dest); } return list; }); } #endregion /// /// 转换成json字符串 /// /// /// public static string ToJsonString(this object source) => JsonConvert.SerializeObject(source, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, Formatting = Formatting.Indented }); /// /// 转换成json字符串 /// /// /// public static async Task ToJsonStringAsync(this object source) => await Task.Run(() => JsonConvert.SerializeObject(source, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, Formatting = Formatting.Indented })); #region UBB、HTML互转 /// /// UBB代码处理函数 /// /// 输入UBB字符串 /// 输出html字符串 public static string UbbToHtml(this string ubbStr) { Regex r; Match m; #region 处理空格 ubbStr = ubbStr.Replace(" ", " "); #endregion #region 处理&符 ubbStr = ubbStr.Replace("&", "&"); #endregion #region 处理单引号 ubbStr = ubbStr.Replace("'", "’"); #endregion #region 处理双引号 ubbStr = ubbStr.Replace("\"", """); #endregion #region html标记符 ubbStr = ubbStr.Replace("<", "<"); ubbStr = ubbStr.Replace(">", ">"); #endregion #region 处理换行 //处理换行,在每个新行的前面添加两个全角空格 r = new Regex(@"(\r\n(( )| )+)(?<正文>\S+)", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "
  " + m.Groups["正文"]); //处理换行,在每个新行的前面添加两个全角空格 ubbStr = ubbStr.Replace("\r\n", "
"); #endregion #region 处[b][/b]标记 r = new Regex(@"(\[b\])([ \S\t]*?)(\[\/b\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[2] + ""); #endregion #region 处[i][/i]标记 r = new Regex(@"(\[i\])([ \S\t]*?)(\[\/i\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[2] + ""); #endregion #region 处[u][/u]标记 r = new Regex(@"(\[U\])([ \S\t]*?)(\[\/U\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[2] + ""); #endregion #region 处[p][/p]标记 //处[p][/p]标记 r = new Regex(@"((\r\n)*\[p\])(.*?)((\r\n)*\[\/p\])", RegexOptions.IgnoreCase | RegexOptions.Singleline); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "

" + m.Groups[3] + "

"); #endregion #region 处[sup][/sup]标记 //处[sup][/sup]标记 r = new Regex(@"(\[sup\])([ \S\t]*?)(\[\/sup\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[2] + ""); #endregion #region 处[sub][/sub]标记 //处[sub][/sub]标记 r = new Regex(@"(\[sub\])([ \S\t]*?)(\[\/sub\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[2] + ""); #endregion #region 处标记 //处标记 r = new Regex(@"(\[url\])([ \S\t]*?)(\[\/url\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[2] + ""); } #endregion #region 处[url=xxx][/url]标记 //处[url=xxx][/url]标记 r = new Regex(@"(\[url=([ \S\t]+)\])([ \S\t]*?)(\[\/url\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[3] + ""); } #endregion #region 处[email][/email]标记 //处[email][/email]标记 r = new Regex(@"(\[email\])([ \S\t]*?)(\[\/email\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[2] + ""); } #endregion #region 处[email=xxx][/email]标记 //处[email=xxx][/email]标记 r = new Regex(@"(\[email=([ \S\t]+)\])([ \S\t]*?)(\[\/email\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[3] + ""); } #endregion #region 处[size=x][/size]标记 //处[size=x][/size]标记 r = new Regex(@"(\[size=([1-7])\])([ \S\t]*?)(\[\/size\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[3] + ""); } #endregion #region 处[color=x][/color]标记 //处[color=x][/color]标记 r = new Regex(@"(\[color=([\S]+)\])([ \S\t]*?)(\[\/color\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[3] + ""); } #endregion #region 处[font=x][/font]标记 //处[font=x][/font]标记 r = new Regex(@"(\[font=([\S]+)\])([ \S\t]*?)(\[\/font\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[3] + ""); } #endregion #region 处理图片链接 //处理图片链接 r = new Regex("\\[picture\\](\\d+?)\\[\\/picture\\]", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), ""); } #endregion #region 处理[align=x][/align] //处理[align=x][/align] r = new Regex(@"(\[align=([\S]+)\])([ \S\t]*?)(\[\/align\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "

" + m.Groups[3] + "

"); } #endregion #region 处[H=x][/H]标记 //处[H=x][/H]标记 r = new Regex(@"(\[H=([1-6])\])([ \S\t]*?)(\[\/H\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[3] + ""); } #endregion #region 处理[list=x][*][/list] //处理[list=x][*][/list] r = new Regex(@"(\[list(=(A|a|I|i| ))?\]([ \S\t]*)\r\n)((\[\*\]([ \S\t]*\r\n))*?)(\[\/list\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { string strLi = m.Groups[5].ToString(); Regex rLi = new Regex(@"\[\*\]([ \S\t]*\r\n?)", RegexOptions.IgnoreCase); Match mLi; for (mLi = rLi.Match(strLi); mLi.Success; mLi = mLi.NextMatch()) strLi = strLi.Replace(mLi.Groups[0].ToString(), "
  • " + mLi.Groups[1]); ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "
      " + m.Groups[4] + "" + strLi + "
    "); } #endregion #region 处[SHADOW=x][/SHADOW]标记 //处[SHADOW=x][/SHADOW]标记 r = new Regex(@"(\[SHADOW=)(\d*?),(#*\w*?),(\d*?)\]([\S\t]*?)(\[\/SHADOW\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[5] + "
    "); } #endregion #region 处[glow=x][/glow]标记 //处[glow=x][/glow]标记 r = new Regex(@"(\[glow=)(\d*?),(#*\w*?),(\d*?)\]([\S\t]*?)(\[\/glow\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[5] + "
    "); } #endregion #region 处[center][/center]标记 r = new Regex(@"(\[center\])([ \S\t]*?)(\[\/center\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "
    " + m.Groups[2] + "
    "); #endregion #region 处[ IMG][ /IMG]标记 r = new Regex(@"(\[IMG\])(http|https|ftp):\/\/([ \S\t]*?)(\[\/IMG\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "
    按此在新窗口浏览图片"); #endregion #region 处[em]标记 r = new Regex(@"(\[em([\S\t]*?)\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), ""); #endregion #region 处[flash=x][/flash]标记 //处[mp=x][/mp]标记 r = new Regex(@"(\[flash=)(\d*?),(\d*?)\]([\S\t]*?)(\[\/flash\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "点击开新窗口欣赏该FLASH动画! [全屏欣赏]

    " + m.Groups[4] + ""); } #endregion #region 处[dir=x][/dir]标记 //处[dir=x][/dir]标记 r = new Regex(@"(\[dir=)(\d*?),(\d*?)\]([\S\t]*?)(\[\/dir\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), ""); } #endregion #region 处[rm=x][/rm]标记 //处[rm=x][/rm]标记 r = new Regex(@"(\[rm=)(\d*?),(\d*?)\]([\S\t]*?)(\[\/rm\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "
    "); } #endregion #region 处[mp=x][/mp]标记 //处[mp=x][/mp]标记 r = new Regex(@"(\[mp=)(\d*?),(\d*?)\]([\S\t]*?)(\[\/mp\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), ""); } #endregion #region 处[qt=x][/qt]标记 //处[qt=x][/qt]标记 r = new Regex(@"(\[qt=)(\d*?),(\d*?)\]([\S\t]*?)(\[\/qt\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), ""); } #endregion #region 处[QUOTE][/QUOTE]标记 r = new Regex(@"(\[QUOTE\])([ \S\t]*?)(\[\/QUOTE\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "
    " + m.Groups[2] + "

    "); #endregion #region 处[move][/move]标记 r = new Regex(@"(\[move\])([ \S\t]*?)(\[\/move\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[2] + ""); #endregion #region 处[FLY][/FLY]标记 r = new Regex(@"(\[FLY\])([ \S\t]*?)(\[\/FLY\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "" + m.Groups[2] + ""); #endregion #region 处[image][/image]标记 //处[image][/image]标记 r = new Regex(@"(\[image\])([ \S\t]*?)(\[\/image\])", RegexOptions.IgnoreCase); for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) { ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "
    "); } #endregion return ubbStr; } /// /// UBB代码处理函数 /// /// 输入UBB字符串 /// 输出html字符串 public static async Task UbbToHtmlAsync(this string ubbStr) => await Task.Run(() => UbbToHtml(ubbStr)); /// /// UBB转HTML方式2 /// /// UBB 代码 /// HTML代码 public static string UbbToHtml2(this string ubbStr) { ubbStr = ubbStr.Replace("&", "&"); ubbStr = ubbStr.Replace("<", "<"); ubbStr = ubbStr.Replace(">", ">"); ubbStr = ubbStr.Replace(" ", " "); //空格 ubbStr = ubbStr.Replace("\n", "
    "); //回车 Regex my = new Regex(@"(\[IMG\])(.[^\[]*)(\[\/IMG\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"按此在新窗口浏览图片screen.width-333)this.width=screen.width-333"">"); my = new Regex(@"\[DIR=*([0-9]*),*([0-9]*)\](.[^\[]*)\[\/DIR]", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @""); my = new Regex(@"\[QT=*([0-9]*),*([0-9]*)\](.[^\[]*)\[\/QT]", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @""); my = new Regex(@"\[MP=*([0-9]*),*([0-9]*)\](.[^\[]*)\[\/MP]", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @""); my = new Regex(@"\[RM=*([0-9]*),*([0-9]*)\](.[^\[]*)\[\/RM]", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"
    "); my = new Regex(@"(\[FLASH\])(.[^\[]*)(\[\/FLASH\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[ZIP\])(.[^\[]*)(\[\/ZIP\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"
    点击下载该文件"); my = new Regex(@"(\[RAR\])(.[^\[]*)(\[\/RAR\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"
    点击下载该文件"); my = new Regex(@"(\[UPLOAD=(.[^\[]*)\])(.[^\[]*)(\[\/UPLOAD\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"
    此主题相关图片如下:
    按此在新窗口浏览图片screen.width-333)this.width=screen.width-333"">"); my = new Regex(@"(\[URL\])(http:\/\/.[^\[]*)(\[\/URL\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[URL\])(.[^\[]*)(\[\/URL\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[URL=(http:\/\/.[^\[]*)\])(.[^\[]*)(\[\/URL\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$3"); my = new Regex(@"(\[URL=(.[^\[]*)\])(.[^\[]*)(\[\/URL\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$3"); my = new Regex(@"(\[EMAIL\])(\S+\@.[^\[]*)(\[\/EMAIL\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[EMAIL=(\S+\@.[^\[]*)\])(.[^\[]*)(\[\/EMAIL\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$3"); my = new Regex(@"^(HTTP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"(HTTP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)$", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"[^>=""](HTTP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"^(FTP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"(FTP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)$", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"[^>=""](FTP://[A-Za-z0-9\.\/=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"^(RTSP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"(RTSP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)$", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"[^>=""](RTSP://[A-Za-z0-9\.\/=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"^(MMS://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"(MMS://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)$", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"[^>=""](MMS://[A-Za-z0-9\.\/=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$1"); my = new Regex(@"(\[HTML\])(.[^\[]*)(\[\/HTML\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"
    以下内容为程序代码:
    $2
    "); my = new Regex(@"(\[CODE\])(.[^\[]*)(\[\/CODE\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"
    以下内容为程序代码:
    $2
    "); my = new Regex(@"(\[COLOR=(.[^\[]*)\])(.[^\[]*)(\[\/COLOR\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$3"); my = new Regex(@"(\[FACE=(.[^\[]*)\])(.[^\[]*)(\[\/FACE\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$3"); my = new Regex(@"(\[ALIGN=(.[^\[]*)\])(.*)(\[\/ALIGN\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"
    $3
    "); my = new Regex(@"(\[QUOTE\])(.*)(\[\/QUOTE\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"
    $2

    "); my = new Regex(@"(\[MOVE\])(.*)(\[\/MOVE\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"\[GLOW=*([0-9]*),*(#*[a-z0-9]*),*([0-9]*)\](.[^\[]*)\[\/GLOW]", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$4
    "); my = new Regex(@"\[SHADOW=*([0-9]*),*(#*[a-z0-9]*),*([0-9]*)\](.[^\[]*)\[\/SHADOW]", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$4
    "); my = new Regex(@"(\[I\])(.[^\[]*)(\[\/I\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[B\])(.[^\[]*)(\[\/U\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[B\])(.[^\[]*)(\[\/B\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[FLY\])(.[^\[]*)(\[\/FLY\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[SIZE=1\])(.[^\[]*)(\[\/SIZE\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[SIZE=2\])(.[^\[]*)(\[\/SIZE\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[SIZE=3\])(.[^\[]*)(\[\/SIZE\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[SIZE=4\])(.[^\[]*)(\[\/SIZE\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"$2"); my = new Regex(@"(\[CENTER\])(.[^\[]*)(\[\/CENTER\])", RegexOptions.IgnoreCase); ubbStr = my.Replace(ubbStr, @"
    $2
    "); return ubbStr; } /// /// UBB转HTML方式2 /// /// UBB 代码 /// HTML代码 public static async Task UbbToHtml2Async(this string ubbStr) => await Task.Run(() => UbbToHtml2(ubbStr)); /// /// Html转UBB /// /// HTML代码 /// UBB代码 public static string HtmltoUBB(this string chr) { if (chr == null) return ""; chr = chr.Replace("<", "<"); chr = chr.Replace(">", ">"); chr = chr.Replace("
    ", " "); chr = Regex.Replace(chr, @"$2", @"[url=(?[^]]*)](?[^]]*)[/url]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[url](?[^]]*)[/url]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$2", @"[email=(?[^]]*)](?[^]]*)[/email]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[email](?[^]]*)[/email]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[flash](?[^]]*)[/flash]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"", @"[img](?[^]]*)[/img]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$2", @"[color=(?[^]]*)](?[^]]*)[/color]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$2", @"[face=(?[^]]*)](?[^]]*)[/face]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[size=1](?[^]]*)[/size]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[size=2](?[^]]*)[/size]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[size=3](?[^]]*)[/size]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[size=4](?[^]]*)[/size]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$2", @"[align=(?[^]]*)](?[^]]*)[/align]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[fly](?[^]]*)[/fly]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[move](?[^]]*)[/move]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$4
    ", @"[glow=(?[^]]*),(?[^]]*),(?[^]]*)](?[^]]*)[/glow]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$4
    ", @"[shadow=(?[^]]*),(?[^]]*),(?[^]]*)](?[^]]*)[/shadow]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[b](?[^]]*)[/b]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[i](?[^]]*)[/i]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"$1", @"[u](?[^]]*)[/u]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"
    $1
    ", @"[code](?[^]]*)[/code]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"
      $1
    ", @"[list](?[^]]*)[/list]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"
      $1
    ", @"[list=1](?[^]]*)[/list]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"
      $1
    ", @"[list=a](?[^]]*)[/list]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"
  • $1
  • ", @"[*](?[^]]*)[/*]", RegexOptions.IgnoreCase); chr = Regex.Replace(chr, @"
    —— 以下是引用 ——
    $1
    ", @"[quote](?.*)[/quote]", RegexOptions.IgnoreCase); return chr; } /// /// Html转UBB /// /// HTML代码 /// UBB代码 public static async Task HtmltoUBBAsync(this string chr) => await Task.Run(() => HtmltoUBB(chr)); #endregion #region 数字互转 /// /// 字符串转int /// /// 源字符串 /// int类型的数字 public static int ToInt32(this string s) { try { return Convert.ToInt32(s); } catch { return 0; } } /// /// 字符串转long /// /// 源字符串 /// int类型的数字 public static long ToInt64(this string s) { try { return Convert.ToInt64(s); } catch { return 0; } } /// /// 字符串转double /// /// 源字符串 /// double类型的数据 public static double ToDouble(this string s) { try { return Convert.ToDouble(s); } catch { return 0; } } /// /// 字符串转decimal /// /// 源字符串 /// int类型的数字 public static decimal ToDecimal(this string s) { try { return Convert.ToDecimal(s); } catch { return 0; } } /// /// 字符串转decimal /// /// 源字符串 /// int类型的数字 public static decimal ToDecimal(this double s) { try { return Convert.ToDecimal(s); } catch { return 0; } } /// /// 字符串转double /// /// 源字符串 /// double类型的数据 public static double ToDouble(this decimal s) { try { return Convert.ToDouble(s); } catch { return 0; } } /// /// 将double转换成int /// /// double类型 /// int类型 public static int ToInt32(this double num) { return (int)Math.Floor(num); } /// /// 将double转换成int /// /// double类型 /// int类型 public static int ToInt32(this decimal num) { return (int)Math.Floor(num); } /// /// 将int转换成double /// /// int类型 /// int类型 public static double ToDouble(this int num) { return num * 1.0; } /// /// 将int转换成decimal /// /// int类型 /// int类型 public static decimal ToDecimal(this int num) { return (decimal)(num * 1.0); } #endregion #region 检测字符串中是否包含列表中的关键词 /// /// 检测字符串中是否包含列表中的关键词 /// /// 源字符串 /// 关键词列表 /// public static bool Contains(this string s, string[] keys) => Regex.IsMatch(s.ToLower(), string.Join("|", keys).ToLower()); #endregion #region 匹配Email /// /// 匹配Email /// /// 源字符串 /// 是否匹配成功,若返回true,则会得到一个Match对象,否则为null /// 匹配对象 public static Match MatchEmail(this string s, out bool isMatch) { Match match = Regex.Match(s, @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"); isMatch = match.Success; return isMatch ? match : null; } /// /// 匹配Email /// /// 源字符串 /// 是否匹配成功 public static bool MatchEmail(this string s) { MatchEmail(s, out bool success); return success; } #endregion #region 匹配完整的URL /// /// 匹配完整格式的URL,支持以下格式的URL,支持中文域名:
    /// 支持不带协议名的网址,支持自适应协议的网址,支持完整路径,支持查询参数,支持锚点,支持锚点查询参数,支持16进制编码
    /// www.baidu.com
    /// www.baidu.com
    /// baidu.com
    /// //www.baidu.com
    /// http://www.baidu.com
    /// https://www.baidu.com
    /// https://baidu.com
    /// ftp://baidu.com
    /// ftp://baidu.com/abc/def
    /// ftp://admin:123456@baidu.com
    /// ftp://admin:123456@baidu.com/abc/def
    /// https://baidu.com:8080
    /// https://baidu.com/abc/def
    /// https://baidu.com:8080/abc/def
    /// https://baidu.com:8080/abc/def/hhh.html
    /// https://baidu.com:8080/abc/def/hhh.html?s=www
    /// https://baidu.com/abc/def/hhh.html?s=w@w{w}!s
    /// https://baidu.com:8080/abc/def/hhh.html?s=www&x=yy+y
    /// https://baidu.com/abc/def/hhh.html?s=www&x=yyy
    /// https://baidu.com:8080/abc/def/hhh.html?s=www&x=yyy#top
    /// https://baidu.com:8080/abc/def/hi_jk-mn%ADF%AA/hhh.html?s=www&x=yyy#top
    /// https://baidu.com:8080/abc/def/hi_j+k-mn%ADF%AA?s=www&x=yyy#top/aaa
    /// https://baidu.com:8080/abc/def/hi_jk-mn%ADF%AA?s=www&x=yyy#top/aaa/bbb/ccc
    /// http://music.163.com/#/my/m/music/empty
    /// http://music.163.com/abc/#/my/m/music/empty
    /// http://music.163.com/def/hhh.html?s=www&x=yyy#/my/m/music/empty
    /// http://music.163.com/def/hhh.html?s=www&x=yyy/#/my/m/music/empty
    /// http://music.163.com/#/search/m/?%23%2Fmy%2Fm%2Fmusic%2Fempty=&s=fade&type=1!k
    ///
    /// 源字符串 /// 是否匹配成功,若返回true,则会得到一个Match对象,否则为null /// 匹配对象 public static Match MatchUrl(this string s, out bool isMatch) { Match match = Regex.Match(s, @"^((\w*):?//)?((\w+)\.|((\S+):(\S+))@)?((\w+)\.(\w+))(:(\d{1,5}))?(/([a-z0-9A-Z-_@{}!+%/]+(\.\w+)?)?(\?([a-z0-9A-Z-_@{}!+%]+=[a-z0-9A-Z-_@{}!+%]+&?)+)?(/?#[a-z0-9A-Z-_@{}!+%/]+)?(\?([a-z0-9A-Z-_@{}!+%]+=[a-z0-9A-Z-_@{}!+%]*&?)+)?)?$"); isMatch = match.Success; return isMatch ? match : null; } /// /// 匹配完整格式的URL,支持以下格式的URL,支持中文域名:
    /// 支持不带协议名的网址,支持自适应协议的网址,支持完整路径,支持查询参数,支持锚点,支持锚点查询参数,支持16进制编码
    /// www.baidu.com
    /// www.baidu.com
    /// baidu.com
    /// //www.baidu.com
    /// http://www.baidu.com
    /// https://www.baidu.com
    /// https://baidu.com
    /// ftp://baidu.com
    /// ftp://baidu.com/abc/def
    /// ftp://admin:123456@baidu.com
    /// ftp://admin:123456@baidu.com/abc/def
    /// https://baidu.com:8080
    /// https://baidu.com/abc/def
    /// https://baidu.com:8080/abc/def
    /// https://baidu.com:8080/abc/def/hhh.html
    /// https://baidu.com:8080/abc/def/hhh.html?s=www
    /// https://baidu.com/abc/def/hhh.html?s=w@w{w}!s
    /// https://baidu.com:8080/abc/def/hhh.html?s=www&x=yy+y
    /// https://baidu.com/abc/def/hhh.html?s=www&x=yyy
    /// https://baidu.com:8080/abc/def/hhh.html?s=www&x=yyy#top
    /// https://baidu.com:8080/abc/def/hi_jk-mn%ADF%AA/hhh.html?s=www&x=yyy#top
    /// https://baidu.com:8080/abc/def/hi_j+k-mn%ADF%AA?s=www&x=yyy#top/aaa
    /// https://baidu.com:8080/abc/def/hi_jk-mn%ADF%AA?s=www&x=yyy#top/aaa/bbb/ccc
    /// http://music.163.com/#/my/m/music/empty
    /// http://music.163.com/abc/#/my/m/music/empty
    /// http://music.163.com/def/hhh.html?s=www&x=yyy#/my/m/music/empty
    /// http://music.163.com/def/hhh.html?s=www&x=yyy/#/my/m/music/empty
    /// http://music.163.com/#/search/m/?%23%2Fmy%2Fm%2Fmusic%2Fempty=&s=fade&type=1!k
    ///
    /// 源字符串 /// 是否匹配成功 public static bool MatchUrl(this string s) { MatchUrl(s, out bool success); return success; } #endregion #region 权威校验身份证号码 /// /// 根据GB11643-1999标准权威校验中国身份证号码的合法性 /// /// 源字符串 /// 是否匹配成功 public static bool MatchIdentifyCard(this string s) { if (s.Length == 18) { long n; if (long.TryParse(s.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(s.Replace('x', '0').Replace('X', '0'), out n) == false) { return false; //数字验证 } string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91"; if (address.IndexOf(s.Remove(2), StringComparison.Ordinal) == -1) { return false; //省份验证 } string birth = s.Substring(6, 8).Insert(6, "-").Insert(4, "-"); DateTime time; if (!DateTime.TryParse(birth, out time)) { return false; //生日验证 } string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(','); string[] wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(','); char[] ai = s.Remove(17).ToCharArray(); int sum = 0; for (int i = 0; i < 17; i++) { sum += wi[i].ToInt32() * ai[i].ToString().ToInt32(); } int y; Math.DivRem(sum, 11, out y); if (arrVarifyCode[y] != s.Substring(17, 1).ToLower()) { return false; //校验码验证 } return true; //符合GB11643-1999标准 } if (s.Length == 15) { long n; if (long.TryParse(s, out n) == false || n < Math.Pow(10, 14)) { return false; //数字验证 } string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91"; if (address.IndexOf(s.Remove(2), StringComparison.Ordinal) == -1) { return false; //省份验证 } string birth = s.Substring(6, 6).Insert(4, "-").Insert(2, "-"); DateTime time; if (DateTime.TryParse(birth, out time) == false) { return false; //生日验证 } return true; } return false; } #endregion #region 校验IP地址的合法性 /// /// 校验IP地址的正确性,同时支持IPv4和IPv6 /// /// 源字符串 /// 是否匹配成功,若返回true,则会得到一个Match对象,否则为null /// 匹配对象 public static Match MatchInetAddress(this string s, out bool isMatch) { Match match; if (s.Contains(":")) { //IPv6 match = Regex.Match(s, "^((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))$"); isMatch = match.Success; } else { //IPv4 match = Regex.Match(s, @"^(\d+)\.(\d+)\.(\d+)\.(\d+)$"); isMatch = match.Success; foreach (Group m in match.Groups) { if (m.Value.ToInt32() < 0 || m.Value.ToInt32() > 255) { isMatch = false; break; } } } return isMatch ? match : null; } /// /// 校验IP地址的正确性,同时支持IPv4和IPv6 /// /// 源字符串 /// 是否匹配成功 public static bool MatchInetAddress(this string s) { MatchInetAddress(s, out bool success); return success; } #endregion #region 校验手机号码的正确性 /// /// 匹配手机号码 /// /// 源字符串 /// 是否匹配成功,若返回true,则会得到一个Match对象,否则为null /// 匹配对象 public static Match MatchPhoneNumber(this string s, out bool isMatch) { Match match = Regex.Match(s, @"^((1[3,5,8][0-9])|(14[5,7])|(17[0,1,3,6,7,8])|(19[8,9]))\d{8}$"); isMatch = match.Success; return isMatch ? match : null; } /// /// 匹配手机号码 /// /// 源字符串 /// 是否匹配成功 public static bool MatchPhoneNumber(this string s) { MatchPhoneNumber(s, out bool success); return success; } #endregion /// /// 严格比较两个对象是否是同一对象 /// /// 自己 /// 需要比较的对象 /// 是否同一对象 public new static bool ReferenceEquals(this object _this, object o) => object.ReferenceEquals(_this, o); /// /// 判断字符串是否为空 /// /// /// public static bool IsNullOrEmpty(this string s) => string.IsNullOrEmpty(s); /// /// 类型直转 /// /// /// /// public static T To(this IConvertible value) { try { return (T)Convert.ChangeType(value, typeof(T)); } catch { return default(T); } } /// /// 字符串转时间 /// /// /// public static DateTime ToDateTime(this string value) { try { return DateTime.Parse(value); } catch { return default(DateTime); } } /// /// 字符串转Guid /// /// /// public static Guid ToGuid(this string s) { return Guid.Parse(s); } /// /// 根据正则替换 /// /// /// 正则表达式 /// 新内容 /// public static string Replace(this string input, Regex regex, string replacement) { return regex.Replace(input, replacement); } /// /// 生成唯一短字符串 /// /// /// 生成的字符串长度,越长冲突的概率越小,默认长度为6,最小长度为5,最大长度为22 /// public static string CreateShortToken(this string str, int length = 6) { var temp = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Trim('='); if (length <= 22) { if (length < 5) { length = 5; } temp = temp.Substring(0, length); } return temp; } /// /// 按字段去重 /// /// /// /// /// /// public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) { HashSet hash = new HashSet(); return source.Where(p => hash.Add(keySelector(p))); } /// /// 将小数截断为8位 /// /// /// public static double Digits8(this double num) { return (long)(num * 1E+8) * 1e-8; } } }