Extensions.cs 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text.RegularExpressions;
  5. using System.Threading.Tasks;
  6. using Masuit.Tools.Security;
  7. using Masuit.Tools.Win32;
  8. using Newtonsoft.Json;
  9. namespace Masuit.Tools
  10. {
  11. /// <summary>
  12. /// 扩展方法
  13. /// </summary>
  14. public static class Extensions
  15. {
  16. #region SyncForEach
  17. /// <summary>
  18. /// 遍历数组
  19. /// </summary>
  20. /// <param name="objs"></param>
  21. /// <param name="action">回调方法</param>
  22. public static void ForEach(this object[] objs, Action<object> action)
  23. {
  24. foreach (var o in objs)
  25. {
  26. action(o);
  27. }
  28. }
  29. /// <summary>
  30. /// 遍历IEnumerable
  31. /// </summary>
  32. /// <param name="objs"></param>
  33. /// <param name="action">回调方法</param>
  34. public static void ForEach(this IEnumerable<object> objs, Action<object> action)
  35. {
  36. foreach (var o in objs)
  37. {
  38. action(o);
  39. }
  40. }
  41. /// <summary>
  42. /// 遍历集合
  43. /// </summary>
  44. /// <param name="objs"></param>
  45. /// <param name="action">回调方法</param>
  46. public static void ForEach(this IList<object> objs, Action<object> action)
  47. {
  48. foreach (var o in objs)
  49. {
  50. action(o);
  51. }
  52. }
  53. /// <summary>
  54. /// 遍历数组
  55. /// </summary>
  56. /// <param name="objs"></param>
  57. /// <param name="action">回调方法</param>
  58. /// <typeparam name="T"></typeparam>
  59. public static void ForEach<T>(this T[] objs, Action<T> action)
  60. {
  61. foreach (var o in objs)
  62. {
  63. action(o);
  64. }
  65. }
  66. /// <summary>
  67. /// 遍历IEnumerable
  68. /// </summary>
  69. /// <param name="objs"></param>
  70. /// <param name="action">回调方法</param>
  71. /// <typeparam name="T"></typeparam>
  72. public static void ForEach<T>(this IEnumerable<T> objs, Action<T> action)
  73. {
  74. foreach (var o in objs)
  75. {
  76. action(o);
  77. }
  78. }
  79. /// <summary>
  80. /// 遍历List
  81. /// </summary>
  82. /// <param name="objs"></param>
  83. /// <param name="action">回调方法</param>
  84. /// <typeparam name="T"></typeparam>
  85. public static void ForEach<T>(this IList<T> objs, Action<T> action)
  86. {
  87. foreach (var o in objs)
  88. {
  89. action(o);
  90. }
  91. }
  92. /// <summary>
  93. /// 遍历数组并返回一个新的List
  94. /// </summary>
  95. /// <param name="objs"></param>
  96. /// <param name="action">回调方法</param>
  97. /// <returns></returns>
  98. public static IEnumerable<T> ForEach<T>(this object[] objs, Func<object, T> action)
  99. {
  100. foreach (var o in objs)
  101. {
  102. yield return action(o);
  103. }
  104. }
  105. /// <summary>
  106. /// 遍历IEnumerable并返回一个新的List
  107. /// </summary>
  108. /// <param name="objs"></param>
  109. /// <param name="action">回调方法</param>
  110. /// <typeparam name="T"></typeparam>
  111. /// <returns></returns>
  112. public static IEnumerable<T> ForEach<T>(this IEnumerable<object> objs, Func<object, T> action)
  113. {
  114. foreach (var o in objs)
  115. {
  116. yield return action(o);
  117. }
  118. }
  119. /// <summary>
  120. /// 遍历List并返回一个新的List
  121. /// </summary>
  122. /// <param name="objs"></param>
  123. /// <param name="action">回调方法</param>
  124. /// <typeparam name="T"></typeparam>
  125. /// <returns></returns>
  126. public static IEnumerable<T> ForEach<T>(this IList<object> objs, Func<object, T> action)
  127. {
  128. foreach (var o in objs)
  129. {
  130. yield return action(o);
  131. }
  132. }
  133. /// <summary>
  134. /// 遍历数组并返回一个新的List
  135. /// </summary>
  136. /// <param name="objs"></param>
  137. /// <param name="action">回调方法</param>
  138. /// <typeparam name="T"></typeparam>
  139. /// <returns></returns>
  140. public static IEnumerable<T> ForEach<T>(this T[] objs, Func<T, T> action)
  141. {
  142. foreach (var o in objs)
  143. {
  144. yield return action(o);
  145. }
  146. }
  147. /// <summary>
  148. /// 遍历IEnumerable并返回一个新的List
  149. /// </summary>
  150. /// <param name="objs"></param>
  151. /// <param name="action">回调方法</param>
  152. /// <typeparam name="T"></typeparam>
  153. /// <returns></returns>
  154. public static IEnumerable<T> ForEach<T>(this IEnumerable<T> objs, Func<T, T> action)
  155. {
  156. foreach (var o in objs)
  157. {
  158. yield return action(o);
  159. }
  160. }
  161. /// <summary>
  162. /// 遍历List并返回一个新的List
  163. /// </summary>
  164. /// <param name="objs"></param>
  165. /// <param name="action">回调方法</param>
  166. /// <typeparam name="T"></typeparam>
  167. /// <returns></returns>
  168. public static IEnumerable<T> ForEach<T>(this IList<T> objs, Func<T, T> action)
  169. {
  170. foreach (var o in objs)
  171. {
  172. yield return action(o);
  173. }
  174. }
  175. #endregion
  176. #region AsyncForEach
  177. /// <summary>
  178. /// 遍历数组
  179. /// </summary>
  180. /// <param name="objs"></param>
  181. /// <param name="action">回调方法</param>
  182. public static async void ForEachAsync(this object[] objs, Action<object> action)
  183. {
  184. await Task.Run(() =>
  185. {
  186. Parallel.ForEach(objs, action);
  187. });
  188. }
  189. /// <summary>
  190. /// 遍历数组
  191. /// </summary>
  192. /// <param name="objs"></param>
  193. /// <param name="action">回调方法</param>
  194. /// <typeparam name="T"></typeparam>
  195. public static async void ForEachAsync<T>(this T[] objs, Action<T> action)
  196. {
  197. await Task.Run(() =>
  198. {
  199. Parallel.ForEach(objs, action);
  200. });
  201. }
  202. /// <summary>
  203. /// 遍历IEnumerable
  204. /// </summary>
  205. /// <param name="objs"></param>
  206. /// <param name="action">回调方法</param>
  207. /// <typeparam name="T"></typeparam>
  208. public static async void ForEachAsync<T>(this IEnumerable<T> objs, Action<T> action)
  209. {
  210. await Task.Run(() =>
  211. {
  212. Parallel.ForEach(objs, action);
  213. });
  214. }
  215. /// <summary>
  216. /// 遍历List
  217. /// </summary>
  218. /// <param name="objs"></param>
  219. /// <param name="action">回调方法</param>
  220. /// <typeparam name="T"></typeparam>
  221. public static async void ForEachAsync<T>(this IList<T> objs, Action<T> action)
  222. {
  223. await Task.Run(() =>
  224. {
  225. Parallel.ForEach(objs, action);
  226. });
  227. }
  228. #endregion
  229. #region Map
  230. /// <summary>
  231. /// 映射到目标类型(浅克隆)
  232. /// </summary>
  233. /// <param name="source">源</param>
  234. /// <typeparam name="TDestination">目标类型</typeparam>
  235. /// <returns>目标类型</returns>
  236. public static TDestination MapTo<TDestination>(this object source) where TDestination : new()
  237. {
  238. TDestination dest = new TDestination();
  239. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source)); });
  240. return dest;
  241. }
  242. /// <summary>
  243. /// 映射到目标类型(浅克隆)
  244. /// </summary>
  245. /// <param name="source">源</param>
  246. /// <typeparam name="TDestination">目标类型</typeparam>
  247. /// <returns>目标类型</returns>
  248. public static async Task<TDestination> MapToAsync<TDestination>(this object source) where TDestination : new()
  249. {
  250. return await Task.Run(() =>
  251. {
  252. TDestination dest = new TDestination();
  253. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source)); });
  254. return dest;
  255. });
  256. }
  257. /// <summary>
  258. /// 映射到目标类型(深克隆)
  259. /// </summary>
  260. /// <param name="source">源</param>
  261. /// <typeparam name="TDestination">目标类型</typeparam>
  262. /// <returns>目标类型</returns>
  263. public static TDestination Map<TDestination>(this object source) where TDestination : new() => JsonConvert.DeserializeObject<TDestination>(JsonConvert.SerializeObject(source));
  264. /// <summary>
  265. /// 映射到目标类型(深克隆)
  266. /// </summary>
  267. /// <param name="source">源</param>
  268. /// <typeparam name="TDestination">目标类型</typeparam>
  269. /// <returns>目标类型</returns>
  270. public static async Task<TDestination> MapAsync<TDestination>(this object source) where TDestination : new() => await Task.Run(() => JsonConvert.DeserializeObject<TDestination>(JsonConvert.SerializeObject(source)));
  271. /// <summary>
  272. /// 复制一个新的对象
  273. /// </summary>
  274. /// <typeparam name="T"></typeparam>
  275. /// <param name="source"></param>
  276. /// <returns></returns>
  277. public static T Copy<T>(this T source) where T : new()
  278. {
  279. T dest = new T();
  280. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source)); });
  281. return dest;
  282. }
  283. /// <summary>
  284. /// 复制到一个现有对象
  285. /// </summary>
  286. /// <typeparam name="T"></typeparam>
  287. /// <param name="source">源对象</param>
  288. /// <param name="dest">目标对象</param>
  289. /// <returns></returns>
  290. public static T CopyTo<T>(this T source, T dest) where T : new()
  291. {
  292. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source)); });
  293. return dest;
  294. }
  295. /// <summary>
  296. /// 复制一个新的对象
  297. /// </summary>
  298. /// <typeparam name="T"></typeparam>
  299. /// <param name="source"></param>
  300. /// <returns></returns>
  301. public static async Task<T> CopyAsync<T>(this T source) where T : new() => await Task.Run(() =>
  302. {
  303. T dest = new T();
  304. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(source)); });
  305. return dest;
  306. });
  307. /// <summary>
  308. /// 映射到目标类型的集合
  309. /// </summary>
  310. /// <param name="source">源</param>
  311. /// <typeparam name="TDestination">目标类型</typeparam>
  312. /// <returns>目标类型集合</returns>
  313. public static IEnumerable<TDestination> ToList<TDestination>(this object[] source) where TDestination : new()
  314. {
  315. foreach (var o in source)
  316. {
  317. var dest = new TDestination();
  318. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); });
  319. yield return dest;
  320. }
  321. }
  322. /// <summary>
  323. /// 映射到目标类型的集合
  324. /// </summary>
  325. /// <param name="source">源</param>
  326. /// <typeparam name="TDestination">目标类型</typeparam>
  327. /// <returns>目标类型集合</returns>
  328. public static async Task<IEnumerable<TDestination>> ToListAsync<TDestination>(this object[] source) where TDestination : new()
  329. {
  330. return await Task.Run(() =>
  331. {
  332. IList<TDestination> list = new List<TDestination>();
  333. foreach (var o in source)
  334. {
  335. var dest = new TDestination();
  336. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); });
  337. list.Add(dest);
  338. }
  339. return list;
  340. });
  341. }
  342. /// <summary>
  343. /// 映射到目标类型的集合
  344. /// </summary>
  345. /// <param name="source">源</param>
  346. /// <typeparam name="TDestination">目标类型</typeparam>
  347. /// <returns>目标类型集合</returns>
  348. public static IEnumerable<TDestination> ToList<TDestination>(this IList<object> source) where TDestination : new()
  349. {
  350. foreach (var o in source)
  351. {
  352. var dest = new TDestination();
  353. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); });
  354. yield return dest;
  355. }
  356. }
  357. /// <summary>
  358. /// 映射到目标类型的集合
  359. /// </summary>
  360. /// <param name="source">源</param>
  361. /// <typeparam name="TDestination">目标类型</typeparam>
  362. /// <returns>目标类型集合</returns>
  363. public static async Task<IEnumerable<TDestination>> ToListAsync<TDestination>(this IList<object> source) where TDestination : new()
  364. {
  365. return await Task.Run(() =>
  366. {
  367. IList<TDestination> list = new List<TDestination>();
  368. foreach (var o in source)
  369. {
  370. var dest = new TDestination();
  371. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); });
  372. list.Add(dest);
  373. }
  374. return list;
  375. });
  376. }
  377. /// <summary>
  378. /// 映射到目标类型的集合
  379. /// </summary>
  380. /// <param name="source">源</param>
  381. /// <typeparam name="TDestination">目标类型</typeparam>
  382. /// <returns>目标类型集合</returns>
  383. public static IEnumerable<TDestination> ToList<TDestination>(this IEnumerable<object> source) where TDestination : new()
  384. {
  385. foreach (var o in source)
  386. {
  387. var dest = new TDestination();
  388. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); });
  389. yield return dest;
  390. }
  391. }
  392. /// <summary>
  393. /// 映射到目标类型的集合
  394. /// </summary>
  395. /// <param name="source">源</param>
  396. /// <typeparam name="TDestination">目标类型</typeparam>
  397. /// <returns>目标类型集合</returns>
  398. public static async Task<IEnumerable<TDestination>> ToListAsync<TDestination>(this IEnumerable<object> source) where TDestination : new()
  399. {
  400. return await Task.Run(() =>
  401. {
  402. IList<TDestination> list = new List<TDestination>();
  403. foreach (var o in source)
  404. {
  405. var dest = new TDestination();
  406. dest.GetType().GetProperties().ForEach(p => { p.SetValue(dest, source.GetType().GetProperty(p.Name)?.GetValue(o)); });
  407. list.Add(dest);
  408. }
  409. return list;
  410. });
  411. }
  412. #endregion
  413. /// <summary>
  414. /// 转换成json字符串
  415. /// </summary>
  416. /// <param name="source"></param>
  417. /// <returns></returns>
  418. public static string ToJsonString(this object source) => JsonConvert.SerializeObject(source);
  419. /// <summary>
  420. /// 转换成json字符串
  421. /// </summary>
  422. /// <param name="source"></param>
  423. /// <returns></returns>
  424. public static async Task<string> ToJsonStringAsync(this object source) => await Task.Run(() => JsonConvert.SerializeObject(source));
  425. #region UBB、HTML互转
  426. /// <summary>
  427. /// UBB代码处理函数
  428. /// </summary>
  429. /// <param name="ubbStr">输入UBB字符串</param>
  430. /// <returns>输出html字符串</returns>
  431. public static string UbbToHtml(this string ubbStr)
  432. {
  433. Regex r;
  434. Match m;
  435. #region 处理空格
  436. ubbStr = ubbStr.Replace(" ", "&nbsp;");
  437. #endregion
  438. #region 处理&符
  439. ubbStr = ubbStr.Replace("&", "&amp;");
  440. #endregion
  441. #region 处理单引号
  442. ubbStr = ubbStr.Replace("'", "’");
  443. #endregion
  444. #region 处理双引号
  445. ubbStr = ubbStr.Replace("\"", "&quot;");
  446. #endregion
  447. #region html标记符
  448. ubbStr = ubbStr.Replace("<", "&lt;");
  449. ubbStr = ubbStr.Replace(">", "&gt;");
  450. #endregion
  451. #region 处理换行
  452. //处理换行,在每个新行的前面添加两个全角空格
  453. r = new Regex(@"(\r\n((&nbsp;)| )+)(?<正文>\S+)", RegexOptions.IgnoreCase);
  454. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<BR>  " + m.Groups["正文"]);
  455. //处理换行,在每个新行的前面添加两个全角空格
  456. ubbStr = ubbStr.Replace("\r\n", "<BR>");
  457. #endregion
  458. #region 处[b][/b]标记
  459. r = new Regex(@"(\[b\])([ \S\t]*?)(\[\/b\])", RegexOptions.IgnoreCase);
  460. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<B>" + m.Groups[2] + "</B>");
  461. #endregion
  462. #region 处[i][/i]标记
  463. r = new Regex(@"(\[i\])([ \S\t]*?)(\[\/i\])", RegexOptions.IgnoreCase);
  464. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<I>" + m.Groups[2] + "</I>");
  465. #endregion
  466. #region 处[u][/u]标记
  467. r = new Regex(@"(\[U\])([ \S\t]*?)(\[\/U\])", RegexOptions.IgnoreCase);
  468. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<U>" + m.Groups[2] + "</U>");
  469. #endregion
  470. #region 处[p][/p]标记
  471. //处[p][/p]标记
  472. r = new Regex(@"((\r\n)*\[p\])(.*?)((\r\n)*\[\/p\])", RegexOptions.IgnoreCase | RegexOptions.Singleline);
  473. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<P class=\"pstyle\">" + m.Groups[3] + "</P>");
  474. #endregion
  475. #region 处[sup][/sup]标记
  476. //处[sup][/sup]标记
  477. r = new Regex(@"(\[sup\])([ \S\t]*?)(\[\/sup\])", RegexOptions.IgnoreCase);
  478. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<SUP>" + m.Groups[2] + "</SUP>");
  479. #endregion
  480. #region 处[sub][/sub]标记
  481. //处[sub][/sub]标记
  482. r = new Regex(@"(\[sub\])([ \S\t]*?)(\[\/sub\])", RegexOptions.IgnoreCase);
  483. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<SUB>" + m.Groups[2] + "</SUB>");
  484. #endregion
  485. #region 处标记
  486. //处标记
  487. r = new Regex(@"(\[url\])([ \S\t]*?)(\[\/url\])", RegexOptions.IgnoreCase);
  488. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  489. {
  490. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<A href=\"" + m.Groups[2] + "\" target=\"_blank\">" + m.Groups[2] + "</A>");
  491. }
  492. #endregion
  493. #region 处[url=xxx][/url]标记
  494. //处[url=xxx][/url]标记
  495. r = new Regex(@"(\[url=([ \S\t]+)\])([ \S\t]*?)(\[\/url\])", RegexOptions.IgnoreCase);
  496. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  497. {
  498. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<A href=\"" + m.Groups[2] + "\" target=\"_blank\">" + m.Groups[3] + "</A>");
  499. }
  500. #endregion
  501. #region 处[email][/email]标记
  502. //处[email][/email]标记
  503. r = new Regex(@"(\[email\])([ \S\t]*?)(\[\/email\])", RegexOptions.IgnoreCase);
  504. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  505. {
  506. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<A href=\"mailto:" + m.Groups[2] + "\" target=\"_blank\">" + m.Groups[2] + "</A>");
  507. }
  508. #endregion
  509. #region 处[email=xxx][/email]标记
  510. //处[email=xxx][/email]标记
  511. r = new Regex(@"(\[email=([ \S\t]+)\])([ \S\t]*?)(\[\/email\])", RegexOptions.IgnoreCase);
  512. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  513. {
  514. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<A href=\"mailto:" + m.Groups[2] + "\" target=\"_blank\">" + m.Groups[3] + "</A>");
  515. }
  516. #endregion
  517. #region 处[size=x][/size]标记
  518. //处[size=x][/size]标记
  519. r = new Regex(@"(\[size=([1-7])\])([ \S\t]*?)(\[\/size\])", RegexOptions.IgnoreCase);
  520. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  521. {
  522. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<FONT SIZE=" + m.Groups[2] + ">" + m.Groups[3] + "</FONT>");
  523. }
  524. #endregion
  525. #region 处[color=x][/color]标记
  526. //处[color=x][/color]标记
  527. r = new Regex(@"(\[color=([\S]+)\])([ \S\t]*?)(\[\/color\])", RegexOptions.IgnoreCase);
  528. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  529. {
  530. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<FONT COLOR=" + m.Groups[2] + ">" + m.Groups[3] + "</FONT>");
  531. }
  532. #endregion
  533. #region 处[font=x][/font]标记
  534. //处[font=x][/font]标记
  535. r = new Regex(@"(\[font=([\S]+)\])([ \S\t]*?)(\[\/font\])", RegexOptions.IgnoreCase);
  536. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  537. {
  538. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<FONT FACE=" + m.Groups[2] + ">" + m.Groups[3] + "</FONT>");
  539. }
  540. #endregion
  541. #region 处理图片链接
  542. //处理图片链接
  543. r = new Regex("\\[picture\\](\\d+?)\\[\\/picture\\]", RegexOptions.IgnoreCase);
  544. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  545. {
  546. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<A href=\"ShowImage.aspx?Type=ALL&Action=forumImage&ImageID=" + m.Groups[1] + "\" target=\"_blank\"><IMG border=0 Title=\"点击打开新窗口查看\" src=\"ShowImage.aspx?Action=forumImage&ImageID=" + m.Groups[1] + "\"></A>");
  547. }
  548. #endregion
  549. #region 处理[align=x][/align]
  550. //处理[align=x][/align]
  551. r = new Regex(@"(\[align=([\S]+)\])([ \S\t]*?)(\[\/align\])", RegexOptions.IgnoreCase);
  552. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  553. {
  554. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<P align=" + m.Groups[2] + ">" + m.Groups[3] + "</P>");
  555. }
  556. #endregion
  557. #region 处[H=x][/H]标记
  558. //处[H=x][/H]标记
  559. r = new Regex(@"(\[H=([1-6])\])([ \S\t]*?)(\[\/H\])", RegexOptions.IgnoreCase);
  560. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  561. {
  562. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<H" + m.Groups[2] + ">" + m.Groups[3] + "</H" + m.Groups[2] + ">");
  563. }
  564. #endregion
  565. #region 处理[list=x][*][/list]
  566. //处理[list=x][*][/list]
  567. r = new Regex(@"(\[list(=(A|a|I|i| ))?\]([ \S\t]*)\r\n)((\[\*\]([ \S\t]*\r\n))*?)(\[\/list\])", RegexOptions.IgnoreCase);
  568. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  569. {
  570. string strLi = m.Groups[5].ToString();
  571. Regex rLi = new Regex(@"\[\*\]([ \S\t]*\r\n?)", RegexOptions.IgnoreCase);
  572. Match mLi;
  573. for (mLi = rLi.Match(strLi); mLi.Success; mLi = mLi.NextMatch()) strLi = strLi.Replace(mLi.Groups[0].ToString(), "<LI>" + mLi.Groups[1]);
  574. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<UL TYPE=\"" + m.Groups[3] + "\"><B>" + m.Groups[4] + "</B>" + strLi + "</UL>");
  575. }
  576. #endregion
  577. #region 处[SHADOW=x][/SHADOW]标记
  578. //处[SHADOW=x][/SHADOW]标记
  579. r = new Regex(@"(\[SHADOW=)(\d*?),(#*\w*?),(\d*?)\]([\S\t]*?)(\[\/SHADOW\])", RegexOptions.IgnoreCase);
  580. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  581. {
  582. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<TABLE WIDTH=" + m.Groups[2] + "STYLE=FILTER:SHADOW(COLOR=" + m.Groups[3] + ",STRENGTH=" + m.Groups[4] + ")>" + m.Groups[5] + "</TABLE>");
  583. }
  584. #endregion
  585. #region 处[glow=x][/glow]标记
  586. //处[glow=x][/glow]标记
  587. r = new Regex(@"(\[glow=)(\d*?),(#*\w*?),(\d*?)\]([\S\t]*?)(\[\/glow\])", RegexOptions.IgnoreCase);
  588. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  589. {
  590. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<TABLE WIDTH=" + m.Groups[2] + " STYLE=FILTER:GLOW(COLOR=" + m.Groups[3] + ", STRENGTH=" + m.Groups[4] + ")>" + m.Groups[5] + "</TABLE>");
  591. }
  592. #endregion
  593. #region 处[center][/center]标记
  594. r = new Regex(@"(\[center\])([ \S\t]*?)(\[\/center\])", RegexOptions.IgnoreCase);
  595. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<CENTER>" + m.Groups[2] + "</CENTER>");
  596. #endregion
  597. #region 处[ IMG][ /IMG]标记
  598. r = new Regex(@"(\[IMG\])(http|https|ftp):\/\/([ \S\t]*?)(\[\/IMG\])", RegexOptions.IgnoreCase);
  599. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<br><a onfocus=this.blur() href=" + m.Groups[2] + "://" + m.Groups[3] + " target=_blank><IMG SRC=" + m.Groups[2] + "://" + m.Groups[3] + " border=0 alt=按此在新窗口浏览图片 onload=javascript:if(screen.width-333<this.width)this.width=screen.width-333></a>");
  600. #endregion
  601. #region 处[em]标记
  602. r = new Regex(@"(\[em([\S\t]*?)\])", RegexOptions.IgnoreCase);
  603. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<img src=pic/em" + m.Groups[2] + ".gif border=0 align=middle>");
  604. #endregion
  605. #region 处[flash=x][/flash]标记
  606. //处[mp=x][/mp]标记
  607. r = new Regex(@"(\[flash=)(\d*?),(\d*?)\]([\S\t]*?)(\[\/flash\])", RegexOptions.IgnoreCase);
  608. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  609. {
  610. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<a href=" + m.Groups[4] + " TARGET=_blank><IMG SRC=pic/swf.gif border=0 alt=点击开新窗口欣赏该FLASH动画!> [全屏欣赏]</a><br><br><OBJECT codeBase=http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0 classid=clsid:D27CDB6E-AE6D-11cf-96B8-444553540000 width=" + m.Groups[2] + " height=" + m.Groups[3] + "><PARAM NAME=movie VALUE=" + m.Groups[4] + "><PARAM NAME=quality VALUE=high><param name=menu value=false><embed src=" + m.Groups[4] + " quality=high menu=false pluginspage=http://www.macromedia.com/go/getflashplayer type=application/x-shockwave-flash width=" + m.Groups[2] + " height=" + m.Groups[3] + ">" + m.Groups[4] + "</embed></OBJECT>");
  611. }
  612. #endregion
  613. #region 处[dir=x][/dir]标记
  614. //处[dir=x][/dir]标记
  615. r = new Regex(@"(\[dir=)(\d*?),(\d*?)\]([\S\t]*?)(\[\/dir\])", RegexOptions.IgnoreCase);
  616. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  617. {
  618. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<object classid=clsid:166B1BCA-3F9C-11CF-8075-444553540000 codebase=http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=7,0,2,0 width=" + m.Groups[2] + " height=" + m.Groups[3] + "><param name=src value=" + m.Groups[4] + "><embed src=" + m.Groups[4] + " pluginspage=http://www.macromedia.com/shockwave/download/ width=" + m.Groups[2] + " height=" + m.Groups[3] + "></embed></object>");
  619. }
  620. #endregion
  621. #region 处[rm=x][/rm]标记
  622. //处[rm=x][/rm]标记
  623. r = new Regex(@"(\[rm=)(\d*?),(\d*?)\]([\S\t]*?)(\[\/rm\])", RegexOptions.IgnoreCase);
  624. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  625. {
  626. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<OBJECT classid=clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA class=OBJECT id=RAOCX width=" + m.Groups[2] + " height=" + m.Groups[3] + "><PARAM NAME=SRC VALUE=" + m.Groups[4] + "><PARAM NAME=CONSOLE VALUE=Clip1><PARAM NAME=CONTROLS VALUE=imagewindow><PARAM NAME=AUTOSTART VALUE=true></OBJECT><br><OBJECT classid=CLSID:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA height=32 id=video2 width=" + m.Groups[2] + "><PARAM NAME=SRC VALUE=" + m.Groups[4] + "><PARAM NAME=AUTOSTART VALUE=-1><PARAM NAME=CONTROLS VALUE=controlpanel><PARAM NAME=CONSOLE VALUE=Clip1></OBJECT>");
  627. }
  628. #endregion
  629. #region 处[mp=x][/mp]标记
  630. //处[mp=x][/mp]标记
  631. r = new Regex(@"(\[mp=)(\d*?),(\d*?)\]([\S\t]*?)(\[\/mp\])", RegexOptions.IgnoreCase);
  632. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  633. {
  634. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<object align=middle classid=CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95 class=OBJECT id=MediaPlayer width=" + m.Groups[2] + " height=" + m.Groups[3] + " ><param name=ShowStatusBar value=-1><param name=Filename value=" + m.Groups[4] + "><embed type=application/x-oleobject codebase=http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701 flename=mp src=" + m.Groups[4] + " width=" + m.Groups[2] + " height=" + m.Groups[3] + "></embed></object>");
  635. }
  636. #endregion
  637. #region 处[qt=x][/qt]标记
  638. //处[qt=x][/qt]标记
  639. r = new Regex(@"(\[qt=)(\d*?),(\d*?)\]([\S\t]*?)(\[\/qt\])", RegexOptions.IgnoreCase);
  640. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  641. {
  642. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<embed src=" + m.Groups[4] + " width=" + m.Groups[2] + " height=" + m.Groups[3] + " autoplay=true loop=false controller=true playeveryframe=false cache=false scale=TOFIT bgcolor=#000000 kioskmode=false targetcache=false pluginspage=http://www.apple.com/quicktime/>");
  643. }
  644. #endregion
  645. #region 处[QUOTE][/QUOTE]标记
  646. r = new Regex(@"(\[QUOTE\])([ \S\t]*?)(\[\/QUOTE\])", RegexOptions.IgnoreCase);
  647. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<div style='border:#CCCCCC 1px dashed; width:94%; color:#999999; padding:3px; background:#F8F8F8'>" + m.Groups[2] + "</div><br /> ");
  648. #endregion
  649. #region 处[move][/move]标记
  650. r = new Regex(@"(\[move\])([ \S\t]*?)(\[\/move\])", RegexOptions.IgnoreCase);
  651. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<MARQUEE scrollamount=3>" + m.Groups[2] + "</MARQUEE>");
  652. #endregion
  653. #region 处[FLY][/FLY]标记
  654. r = new Regex(@"(\[FLY\])([ \S\t]*?)(\[\/FLY\])", RegexOptions.IgnoreCase);
  655. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch()) ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<MARQUEE width=80% behavior=alternate scrollamount=3>" + m.Groups[2] + "</MARQUEE>");
  656. #endregion
  657. #region 处[image][/image]标记
  658. //处[image][/image]标记
  659. r = new Regex(@"(\[image\])([ \S\t]*?)(\[\/image\])", RegexOptions.IgnoreCase);
  660. for (m = r.Match(ubbStr); m.Success; m = m.NextMatch())
  661. {
  662. ubbStr = ubbStr.Replace(m.Groups[0].ToString(), "<img src=\"" + m.Groups[2] + "\" border=0 align=middle><br>");
  663. }
  664. #endregion
  665. return ubbStr;
  666. }
  667. /// <summary>
  668. /// UBB代码处理函数
  669. /// </summary>
  670. /// <param name="ubbStr">输入UBB字符串</param>
  671. /// <returns>输出html字符串</returns>
  672. public static async Task<string> UbbToHtmlAsync(this string ubbStr) => await Task.Run(() => UbbToHtml(ubbStr));
  673. /// <summary>
  674. /// UBB转HTML方式2
  675. /// </summary>
  676. /// <param name="ubbStr">UBB 代码</param>
  677. /// <returns>HTML代码</returns>
  678. public static string UbbToHtml2(this string ubbStr)
  679. {
  680. ubbStr = ubbStr.Replace("&", "&amp;");
  681. ubbStr = ubbStr.Replace("<", "&lt;");
  682. ubbStr = ubbStr.Replace(">", "&gt;");
  683. ubbStr = ubbStr.Replace(" ", "&nbsp;"); //空格
  684. ubbStr = ubbStr.Replace("\n", "<br>"); //回车
  685. Regex my = new Regex(@"(\[IMG\])(.[^\[]*)(\[\/IMG\])", RegexOptions.IgnoreCase);
  686. ubbStr = my.Replace(ubbStr, @"<a href=""$2"" target=_blank><IMG SRC=""$2"" border=0 alt=按此在新窗口浏览图片 onload=""javascript:if(this.width>screen.width-333)this.width=screen.width-333""></a>");
  687. my = new Regex(@"\[DIR=*([0-9]*),*([0-9]*)\](.[^\[]*)\[\/DIR]", RegexOptions.IgnoreCase);
  688. ubbStr = my.Replace(ubbStr, @"<object classid=clsid:166B1BCA-3F9C-11CF-8075-444553540000 codebase=http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=7,0,2,0 width=$1 height=$2><param name=src value=$3><embed src=$3 pluginspage=http://www.macromedia.com/shockwave/download/ width=$1 height=$2></embed></object>");
  689. my = new Regex(@"\[QT=*([0-9]*),*([0-9]*)\](.[^\[]*)\[\/QT]", RegexOptions.IgnoreCase);
  690. ubbStr = my.Replace(ubbStr, @"<embed src=$3 width=$1 height=$2 autoplay=true loop=false controller=true playeveryframe=false cache=false scale=TOFIT bgcolor=#000000 kioskmode=false targetcache=false pluginspage=http://www.apple.com/quicktime/>");
  691. my = new Regex(@"\[MP=*([0-9]*),*([0-9]*)\](.[^\[]*)\[\/MP]", RegexOptions.IgnoreCase);
  692. ubbStr = my.Replace(ubbStr, @"<object align=middle classid=CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95 class=OBJECT id=MediaPlayer width=$1 height=$2 ><param name=ShowStatusBar value=-1><param name=Filename value=$3><embed type=application/x-oleobject codebase=http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701 flename=mp src=$3 width=$1 height=$2></embed></object>");
  693. my = new Regex(@"\[RM=*([0-9]*),*([0-9]*)\](.[^\[]*)\[\/RM]", RegexOptions.IgnoreCase);
  694. ubbStr = my.Replace(ubbStr, @"<OBJECT classid=clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA class=OBJECT id=RAOCX width=$1 height=$2><PARAM NAME=SRC VALUE=$3><PARAM NAME=CONSOLE VALUE=Clip1><PARAM NAME=CONTROLS VALUE=imagewindow><PARAM NAME=AUTOSTART VALUE=true></OBJECT><br><OBJECT classid=CLSID:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA height=32 id=video2 width=$1><PARAM NAME=SRC VALUE=$3><PARAM NAME=AUTOSTART VALUE=-1><PARAM NAME=CONTROLS VALUE=controlpanel><PARAM NAME=CONSOLE VALUE=Clip1></OBJECT>");
  695. my = new Regex(@"(\[FLASH\])(.[^\[]*)(\[\/FLASH\])", RegexOptions.IgnoreCase);
  696. ubbStr = my.Replace(ubbStr, @"<OBJECT codeBase=http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=4,0,2,0 classid=clsid:D27CDB6E-AE6D-11cf-96B8-444553540000 width=500 height=400><PARAM NAME=movie VALUE=""$2""><PARAM NAME=quality VALUE=high><embed src=""$2"" quality=high pluginspage='http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash' type='application/x-shockwave-flash' width=500 height=400>$2</embed></OBJECT>");
  697. my = new Regex(@"(\[ZIP\])(.[^\[]*)(\[\/ZIP\])", RegexOptions.IgnoreCase);
  698. ubbStr = my.Replace(ubbStr, @"<br><IMG SRC=pic/zip.gif border=0> <a href=""$2"">点击下载该文件</a>");
  699. my = new Regex(@"(\[RAR\])(.[^\[]*)(\[\/RAR\])", RegexOptions.IgnoreCase);
  700. ubbStr = my.Replace(ubbStr, @"<br><IMG SRC=pic/rar.gif border=0> <a href=""$2"">点击下载该文件</a>");
  701. my = new Regex(@"(\[UPLOAD=(.[^\[]*)\])(.[^\[]*)(\[\/UPLOAD\])", RegexOptions.IgnoreCase);
  702. ubbStr = my.Replace(ubbStr, @"<br><IMG SRC=""pic/$2.gif"" border=0>此主题相关图片如下:<br><A HREF=""$3"" TARGET=_blank><IMG SRC=""$3"" border=0 alt=按此在新窗口浏览图片 onload=""javascript:if(this.width>screen.width-333)this.width=screen.width-333""></A>");
  703. my = new Regex(@"(\[URL\])(http:\/\/.[^\[]*)(\[\/URL\])", RegexOptions.IgnoreCase);
  704. ubbStr = my.Replace(ubbStr, @"<A HREF=""$2"" TARGET=_blank>$2</A>");
  705. my = new Regex(@"(\[URL\])(.[^\[]*)(\[\/URL\])", RegexOptions.IgnoreCase);
  706. ubbStr = my.Replace(ubbStr, @"<A HREF=""http://$2"" TARGET=_blank>$2</A>");
  707. my = new Regex(@"(\[URL=(http:\/\/.[^\[]*)\])(.[^\[]*)(\[\/URL\])", RegexOptions.IgnoreCase);
  708. ubbStr = my.Replace(ubbStr, @"<A HREF=""$2"" TARGET=_blank>$3</A>");
  709. my = new Regex(@"(\[URL=(.[^\[]*)\])(.[^\[]*)(\[\/URL\])", RegexOptions.IgnoreCase);
  710. ubbStr = my.Replace(ubbStr, @"<A HREF=""http://$2"" TARGET=_blank>$3</A>");
  711. my = new Regex(@"(\[EMAIL\])(\S+\@.[^\[]*)(\[\/EMAIL\])", RegexOptions.IgnoreCase);
  712. ubbStr = my.Replace(ubbStr, @"<A HREF=""mailto:$2"">$2</A>");
  713. my = new Regex(@"(\[EMAIL=(\S+\@.[^\[]*)\])(.[^\[]*)(\[\/EMAIL\])", RegexOptions.IgnoreCase);
  714. ubbStr = my.Replace(ubbStr, @"<A HREF=""mailto:$2"" TARGET=_blank>$3</A>");
  715. my = new Regex(@"^(HTTP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase);
  716. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  717. my = new Regex(@"(HTTP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)$", RegexOptions.IgnoreCase);
  718. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  719. my = new Regex(@"[^>=""](HTTP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase);
  720. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  721. my = new Regex(@"^(FTP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase);
  722. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  723. my = new Regex(@"(FTP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)$", RegexOptions.IgnoreCase);
  724. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  725. my = new Regex(@"[^>=""](FTP://[A-Za-z0-9\.\/=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase);
  726. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  727. my = new Regex(@"^(RTSP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase);
  728. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  729. my = new Regex(@"(RTSP://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)$", RegexOptions.IgnoreCase);
  730. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  731. my = new Regex(@"[^>=""](RTSP://[A-Za-z0-9\.\/=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase);
  732. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  733. my = new Regex(@"^(MMS://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase);
  734. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  735. my = new Regex(@"(MMS://[A-Za-z0-9\./=\?%\-&_~`@':+!]+)$", RegexOptions.IgnoreCase);
  736. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  737. my = new Regex(@"[^>=""](MMS://[A-Za-z0-9\.\/=\?%\-&_~`@':+!]+)", RegexOptions.IgnoreCase);
  738. ubbStr = my.Replace(ubbStr, @"<a target=_blank href=$1>$1</a>");
  739. my = new Regex(@"(\[HTML\])(.[^\[]*)(\[\/HTML\])", RegexOptions.IgnoreCase);
  740. ubbStr = my.Replace(ubbStr, @"<table width='100%' border='0' cellspacing='0' cellpadding='6' bgcolor=''><td><b>以下内容为程序代码:</b><br>$2</td></table>");
  741. my = new Regex(@"(\[CODE\])(.[^\[]*)(\[\/CODE\])", RegexOptions.IgnoreCase);
  742. ubbStr = my.Replace(ubbStr, @"<table width='100%' border='0' cellspacing='0' cellpadding='6' bgcolor=''><td><b>以下内容为程序代码:</b><br>$2</td></table>");
  743. my = new Regex(@"(\[COLOR=(.[^\[]*)\])(.[^\[]*)(\[\/COLOR\])", RegexOptions.IgnoreCase);
  744. ubbStr = my.Replace(ubbStr, @"<font COLOR=$2>$3</font>");
  745. my = new Regex(@"(\[FACE=(.[^\[]*)\])(.[^\[]*)(\[\/FACE\])", RegexOptions.IgnoreCase);
  746. ubbStr = my.Replace(ubbStr, @"<font FACE=$2>$3</font>");
  747. my = new Regex(@"(\[ALIGN=(.[^\[]*)\])(.*)(\[\/ALIGN\])", RegexOptions.IgnoreCase);
  748. ubbStr = my.Replace(ubbStr, @"<div ALIGN=$2>$3</div>");
  749. my = new Regex(@"(\[QUOTE\])(.*)(\[\/QUOTE\])", RegexOptions.IgnoreCase);
  750. ubbStr = my.Replace(ubbStr, @"<table cellpadding=0 cellspacing=0 border=0 WIDTH=94% bgcolor=#000000 align=center><tr><td><table width=100% cellpadding=5 cellspacing=1 border=0><TR><TD BGCOLOR=''>$2</table></table><br>");
  751. my = new Regex(@"(\[MOVE\])(.*)(\[\/MOVE\])", RegexOptions.IgnoreCase);
  752. ubbStr = my.Replace(ubbStr, @"<MARQUEE scrollamount=3>$2</marquee>");
  753. my = new Regex(@"\[GLOW=*([0-9]*),*(#*[a-z0-9]*),*([0-9]*)\](.[^\[]*)\[\/GLOW]", RegexOptions.IgnoreCase);
  754. ubbStr = my.Replace(ubbStr, @"<table width=$1 style=""filter:glow(color=$2, strength=$3)"">$4</table>");
  755. my = new Regex(@"\[SHADOW=*([0-9]*),*(#*[a-z0-9]*),*([0-9]*)\](.[^\[]*)\[\/SHADOW]", RegexOptions.IgnoreCase);
  756. ubbStr = my.Replace(ubbStr, @"<table width=$1 style=""filter:shadow(color=$2, strength=$3)"">$4</table>");
  757. my = new Regex(@"(\[I\])(.[^\[]*)(\[\/I\])", RegexOptions.IgnoreCase);
  758. ubbStr = my.Replace(ubbStr, @"<i>$2</i>");
  759. my = new Regex(@"(\[B\])(.[^\[]*)(\[\/U\])", RegexOptions.IgnoreCase);
  760. ubbStr = my.Replace(ubbStr, @"<u>$2</u>");
  761. my = new Regex(@"(\[B\])(.[^\[]*)(\[\/B\])", RegexOptions.IgnoreCase);
  762. ubbStr = my.Replace(ubbStr, @"<b>$2</b>");
  763. my = new Regex(@"(\[FLY\])(.[^\[]*)(\[\/FLY\])", RegexOptions.IgnoreCase);
  764. ubbStr = my.Replace(ubbStr, @"<marquee onmouseover='this.stop();' onmouseout='this.start();'>$2</marquee>");
  765. my = new Regex(@"(\[SIZE=1\])(.[^\[]*)(\[\/SIZE\])", RegexOptions.IgnoreCase);
  766. ubbStr = my.Replace(ubbStr, @"<font size=1>$2</font>");
  767. my = new Regex(@"(\[SIZE=2\])(.[^\[]*)(\[\/SIZE\])", RegexOptions.IgnoreCase);
  768. ubbStr = my.Replace(ubbStr, @"<font size=2>$2</font>");
  769. my = new Regex(@"(\[SIZE=3\])(.[^\[]*)(\[\/SIZE\])", RegexOptions.IgnoreCase);
  770. ubbStr = my.Replace(ubbStr, @"<font size=3>$2</font>");
  771. my = new Regex(@"(\[SIZE=4\])(.[^\[]*)(\[\/SIZE\])", RegexOptions.IgnoreCase);
  772. ubbStr = my.Replace(ubbStr, @"<font size=4>$2</font>");
  773. my = new Regex(@"(\[CENTER\])(.[^\[]*)(\[\/CENTER\])", RegexOptions.IgnoreCase);
  774. ubbStr = my.Replace(ubbStr, @"<center>$2</center>");
  775. return ubbStr;
  776. }
  777. /// <summary>
  778. /// UBB转HTML方式2
  779. /// </summary>
  780. /// <param name="ubbStr">UBB 代码</param>
  781. /// <returns>HTML代码</returns>
  782. public static async Task<string> UbbToHtml2Async(this string ubbStr) => await Task.Run(() => UbbToHtml2(ubbStr));
  783. /// <summary>
  784. /// Html转UBB
  785. /// </summary>
  786. /// <param name="chr">HTML代码</param>
  787. /// <returns>UBB代码</returns>
  788. public static string HtmltoUBB(this string chr)
  789. {
  790. if (chr == null) return "";
  791. chr = chr.Replace("&lt", "<");
  792. chr = chr.Replace("&gt", ">");
  793. chr = chr.Replace("<br/>", " ");
  794. chr = Regex.Replace(chr, @"<a href=$1 target=_blank>$2</a>", @"[url=(?<x>[^]]*)](?<y>[^]]*)[/url]", RegexOptions.IgnoreCase);
  795. chr = Regex.Replace(chr, @"<a href=$1 target=_blank>$1</a>", @"[url](?<x>[^]]*)[/url]", RegexOptions.IgnoreCase);
  796. chr = Regex.Replace(chr, @"<a href=$1>$2</a>", @"[email=(?<x>[^]]*)](?<y>[^]]*)[/email]", RegexOptions.IgnoreCase);
  797. chr = Regex.Replace(chr, @"<a href=$1>$1</a>", @"[email](?<x>[^]]*)[/email]", RegexOptions.IgnoreCase);
  798. chr = Regex.Replace(chr, @"<OBJECT codeBase=http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=4,0,2,0 classid=clsid:D27CDB6E-AE6D-11cf-96B8-444553540000 width=500 height=400><PARAM NAME=movie VALUE=""$1""><PARAM NAME=quality VALUE=high><embed src=""$1"" quality=high pluginspage='http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash' type='application/x-shockwave-flash' width=500 height=400>$1</embed></OBJECT>", @"[flash](?<x>[^]]*)[/flash]", RegexOptions.IgnoreCase);
  799. chr = Regex.Replace(chr, @"<IMG SRC=""$1"" border=0>", @"[img](?<x>[^]]*)[/img]", RegexOptions.IgnoreCase);
  800. chr = Regex.Replace(chr, @"<font color=$1>$2</font>", @"[color=(?<x>[^]]*)](?<y>[^]]*)[/color]", RegexOptions.IgnoreCase);
  801. chr = Regex.Replace(chr, @"<font face=$1>$2</font>", @"[face=(?<x>[^]]*)](?<y>[^]]*)[/face]", RegexOptions.IgnoreCase);
  802. chr = Regex.Replace(chr, @"<font size=1>$1</font>", @"[size=1](?<x>[^]]*)[/size]", RegexOptions.IgnoreCase);
  803. chr = Regex.Replace(chr, @"<font size=2>$1</font>", @"[size=2](?<x>[^]]*)[/size]", RegexOptions.IgnoreCase);
  804. chr = Regex.Replace(chr, @"<font size=3>$1</font>", @"[size=3](?<x>[^]]*)[/size]", RegexOptions.IgnoreCase);
  805. chr = Regex.Replace(chr, @"<font size=4>$1</font>", @"[size=4](?<x>[^]]*)[/size]", RegexOptions.IgnoreCase);
  806. chr = Regex.Replace(chr, @"<align=$1>$2</align>", @"[align=(?<x>[^]]*)](?<y>[^]]*)[/align]", RegexOptions.IgnoreCase);
  807. chr = Regex.Replace(chr, @"<marquee width=90% behavior=alternate scrollamount=3>$1</marquee>", @"[fly](?<x>[^]]*)[/fly]", RegexOptions.IgnoreCase);
  808. chr = Regex.Replace(chr, @"<marquee scrollamount=3>$1</marquee>", @"[move](?<x>[^]]*)[/move]", RegexOptions.IgnoreCase);
  809. chr = Regex.Replace(chr, @"<table width=$1 style='filter:glow(color=$2, strength=$3)'>$4</table>", @"[glow=(?<x>[^]]*),(?<y>[^]]*),(?<z>[^]]*)](?<w>[^]]*)[/glow]", RegexOptions.IgnoreCase);
  810. chr = Regex.Replace(chr, @"<table width=$1 style='filter:shadow(color=$2, strength=$3)'>$4</table>", @"[shadow=(?<x>[^]]*),(?<y>[^]]*),(?<z>[^]]*)](?<w>[^]]*)[/shadow]", RegexOptions.IgnoreCase);
  811. chr = Regex.Replace(chr, @"<b>$1</b>", @"[b](?<x>[^]]*)[/b]", RegexOptions.IgnoreCase);
  812. chr = Regex.Replace(chr, @"<i>$1</i>", @"[i](?<x>[^]]*)[/i]", RegexOptions.IgnoreCase);
  813. chr = Regex.Replace(chr, @"<u>$1</u>", @"[u](?<x>[^]]*)[/u]", RegexOptions.IgnoreCase);
  814. chr = Regex.Replace(chr, @"<pre id=code><font size=1 face='Verdana, Arial' id=code>$1</font id=code></pre id=code>", @"[code](?<x>[^]]*)[/code]", RegexOptions.IgnoreCase);
  815. chr = Regex.Replace(chr, @"<ul>$1</ul>", @"[list](?<x>[^]]*)[/list]", RegexOptions.IgnoreCase);
  816. chr = Regex.Replace(chr, @"<ol type=1>$1</ol id=1>", @"[list=1](?<x>[^]]*)[/list]", RegexOptions.IgnoreCase);
  817. chr = Regex.Replace(chr, @"<ol type=a>$1</ol id=a>", @"[list=a](?<x>[^]]*)[/list]", RegexOptions.IgnoreCase);
  818. chr = Regex.Replace(chr, @"<li>$1</li>", @"[*](?<x>[^]]*)[/*]", RegexOptions.IgnoreCase);
  819. chr = Regex.Replace(chr, @"<center>—— 以下是引用 ——<table border='1' width='80%' cellpadding='10' cellspacing='0' ><tr><td>$1</td></tr></table></center>", @"[quote](?<x>.*)[/quote]", RegexOptions.IgnoreCase);
  820. return chr;
  821. }
  822. /// <summary>
  823. /// Html转UBB
  824. /// </summary>
  825. /// <param name="chr">HTML代码</param>
  826. /// <returns>UBB代码</returns>
  827. public static async Task<string> HtmltoUBBAsync(this string chr) => await Task.Run(() => HtmltoUBB(chr));
  828. #endregion
  829. #region 数字互转
  830. /// <summary>
  831. /// 字符串转int
  832. /// </summary>
  833. /// <param name="s">源字符串</param>
  834. /// <returns>int类型的数字</returns>
  835. public static int ToInt32(this string s)
  836. {
  837. try
  838. {
  839. return Convert.ToInt32(s);
  840. }
  841. catch
  842. {
  843. return 0;
  844. }
  845. }
  846. /// <summary>
  847. /// 字符串转long
  848. /// </summary>
  849. /// <param name="s">源字符串</param>
  850. /// <returns>int类型的数字</returns>
  851. public static long ToInt64(this string s)
  852. {
  853. try
  854. {
  855. return Convert.ToInt64(s);
  856. }
  857. catch
  858. {
  859. return 0;
  860. }
  861. }
  862. /// <summary>
  863. /// 字符串转double
  864. /// </summary>
  865. /// <param name="s">源字符串</param>
  866. /// <returns>double类型的数据</returns>
  867. public static double ToDouble(this string s)
  868. {
  869. try
  870. {
  871. return Convert.ToDouble(s);
  872. }
  873. catch
  874. {
  875. return 0;
  876. }
  877. }
  878. /// <summary>
  879. /// 字符串转decimal
  880. /// </summary>
  881. /// <param name="s">源字符串</param>
  882. /// <returns>int类型的数字</returns>
  883. public static decimal ToDecimal(this string s)
  884. {
  885. try
  886. {
  887. return Convert.ToDecimal(s);
  888. }
  889. catch
  890. {
  891. return 0;
  892. }
  893. }
  894. /// <summary>
  895. /// 字符串转decimal
  896. /// </summary>
  897. /// <param name="s">源字符串</param>
  898. /// <returns>int类型的数字</returns>
  899. public static decimal ToDecimal(this double s)
  900. {
  901. try
  902. {
  903. return Convert.ToDecimal(s);
  904. }
  905. catch
  906. {
  907. return 0;
  908. }
  909. }
  910. /// <summary>
  911. /// 字符串转double
  912. /// </summary>
  913. /// <param name="s">源字符串</param>
  914. /// <returns>double类型的数据</returns>
  915. public static double ToDouble(this decimal s)
  916. {
  917. try
  918. {
  919. return Convert.ToDouble(s);
  920. }
  921. catch
  922. {
  923. return 0;
  924. }
  925. }
  926. /// <summary>
  927. /// 将double转换成int
  928. /// </summary>
  929. /// <param name="num">double类型</param>
  930. /// <returns>int类型</returns>
  931. public static int ToInt32(this double num)
  932. {
  933. return (int)Math.Floor(num);
  934. }
  935. /// <summary>
  936. /// 将double转换成int
  937. /// </summary>
  938. /// <param name="num">double类型</param>
  939. /// <returns>int类型</returns>
  940. public static int ToInt32(this decimal num)
  941. {
  942. return (int)Math.Floor(num);
  943. }
  944. /// <summary>
  945. /// 将int转换成double
  946. /// </summary>
  947. /// <param name="num">int类型</param>
  948. /// <returns>int类型</returns>
  949. public static double ToDouble(this int num)
  950. {
  951. return num * 1.0;
  952. }
  953. /// <summary>
  954. /// 将int转换成decimal
  955. /// </summary>
  956. /// <param name="num">int类型</param>
  957. /// <returns>int类型</returns>
  958. public static decimal ToDecimal(this int num)
  959. {
  960. return (decimal)(num * 1.0);
  961. }
  962. #endregion
  963. #region 检测字符串中是否包含列表中的关键词
  964. /// <summary>
  965. /// 检测字符串中是否包含列表中的关键词
  966. /// </summary>
  967. /// <param name="s">源字符串</param>
  968. /// <param name="keys">关键词列表</param>
  969. /// <returns></returns>
  970. public static bool Contains(this string s, string[] keys) => Regex.IsMatch(s.ToLower(), string.Join("|", keys).ToLower());
  971. #endregion
  972. #region 匹配Email
  973. /// <summary>
  974. /// 匹配Email
  975. /// </summary>
  976. /// <param name="s">源字符串</param>
  977. /// <param name="isMatch">是否匹配成功,若返回true,则会得到一个Match对象,否则为null</param>
  978. /// <returns>匹配对象</returns>
  979. public static Match MatchEmail(this string s, out bool isMatch)
  980. {
  981. Match match = Regex.Match(s, @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$");
  982. isMatch = match.Success;
  983. return isMatch ? match : null;
  984. }
  985. /// <summary>
  986. /// 匹配Email
  987. /// </summary>
  988. /// <param name="s">源字符串</param>
  989. /// <returns>是否匹配成功</returns>
  990. public static bool MatchEmail(this string s)
  991. {
  992. MatchEmail(s, out bool success);
  993. return success;
  994. }
  995. #endregion
  996. #region 匹配完整的URL
  997. /// <summary>
  998. /// 匹配完整格式的URL,支持以下格式的URL,支持中文域名:<br/>
  999. /// 支持不带协议名的网址,支持自适应协议的网址,支持完整路径,支持查询参数,支持锚点,支持锚点查询参数,支持16进制编码<br/>
  1000. /// www.baidu.com <br/>
  1001. /// www.baidu.com <br/>
  1002. /// baidu.com <br/>
  1003. /// //www.baidu.com <br/>
  1004. /// http://www.baidu.com <br/>
  1005. /// https://www.baidu.com <br/>
  1006. /// https://baidu.com <br/>
  1007. /// ftp://baidu.com <br/>
  1008. /// ftp://baidu.com/abc/def <br/>
  1009. /// ftp://admin:[email protected] <br/>
  1010. /// ftp://admin:[email protected]/abc/def <br/>
  1011. /// https://baidu.com:8080 <br/>
  1012. /// https://baidu.com/abc/def <br/>
  1013. /// https://baidu.com:8080/abc/def <br/>
  1014. /// https://baidu.com:8080/abc/def/hhh.html <br/>
  1015. /// https://baidu.com:8080/abc/def/hhh.html?s=www <br/>
  1016. /// https://baidu.com/abc/def/hhh.html?s=w@w{w}!s <br/>
  1017. /// https://baidu.com:8080/abc/def/hhh.html?s=www&amp;x=yy+y <br/>
  1018. /// https://baidu.com/abc/def/hhh.html?s=www&amp;x=yyy <br/>
  1019. /// https://baidu.com:8080/abc/def/hhh.html?s=www&amp;x=yyy#top <br/>
  1020. /// https://baidu.com:8080/abc/def/hi_jk-mn%ADF%AA/hhh.html?s=www&amp;x=yyy#top <br/>
  1021. /// https://baidu.com:8080/abc/def/hi_j+k-mn%ADF%AA?s=www&amp;x=yyy#top/aaa <br/>
  1022. /// https://baidu.com:8080/abc/def/hi_jk-mn%ADF%AA?s=www&amp;x=yyy#top/aaa/bbb/ccc <br/>
  1023. /// http://music.163.com/#/my/m/music/empty <br/>
  1024. /// http://music.163.com/abc/#/my/m/music/empty <br/>
  1025. /// http://music.163.com/def/hhh.html?s=www&amp;x=yyy#/my/m/music/empty <br/>
  1026. /// http://music.163.com/def/hhh.html?s=www&amp;x=yyy/#/my/m/music/empty <br/>
  1027. /// http://music.163.com/#/search/m/?%23%2Fmy%2Fm%2Fmusic%2Fempty=&amp;s=fade&amp;type=1!k <br/>
  1028. /// </summary>
  1029. /// <param name="s">源字符串</param>
  1030. /// <param name="isMatch">是否匹配成功,若返回true,则会得到一个Match对象,否则为null</param>
  1031. /// <returns>匹配对象</returns>
  1032. public static Match MatchUrl(this string s, out bool isMatch)
  1033. {
  1034. 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-_@{}!+%]*&?)+)?)?$");
  1035. isMatch = match.Success;
  1036. return isMatch ? match : null;
  1037. }
  1038. /// <summary>
  1039. /// 匹配完整格式的URL,支持以下格式的URL,支持中文域名:<br/>
  1040. /// 支持不带协议名的网址,支持自适应协议的网址,支持完整路径,支持查询参数,支持锚点,支持锚点查询参数,支持16进制编码<br/>
  1041. /// www.baidu.com <br/>
  1042. /// www.baidu.com <br/>
  1043. /// baidu.com <br/>
  1044. /// //www.baidu.com <br/>
  1045. /// http://www.baidu.com <br/>
  1046. /// https://www.baidu.com <br/>
  1047. /// https://baidu.com <br/>
  1048. /// ftp://baidu.com <br/>
  1049. /// ftp://baidu.com/abc/def <br/>
  1050. /// ftp://admin:[email protected] <br/>
  1051. /// ftp://admin:[email protected]/abc/def <br/>
  1052. /// https://baidu.com:8080 <br/>
  1053. /// https://baidu.com/abc/def <br/>
  1054. /// https://baidu.com:8080/abc/def <br/>
  1055. /// https://baidu.com:8080/abc/def/hhh.html <br/>
  1056. /// https://baidu.com:8080/abc/def/hhh.html?s=www <br/>
  1057. /// https://baidu.com/abc/def/hhh.html?s=w@w{w}!s <br/>
  1058. /// https://baidu.com:8080/abc/def/hhh.html?s=www&amp;x=yy+y <br/>
  1059. /// https://baidu.com/abc/def/hhh.html?s=www&amp;x=yyy <br/>
  1060. /// https://baidu.com:8080/abc/def/hhh.html?s=www&amp;x=yyy#top <br/>
  1061. /// https://baidu.com:8080/abc/def/hi_jk-mn%ADF%AA/hhh.html?s=www&amp;x=yyy#top <br/>
  1062. /// https://baidu.com:8080/abc/def/hi_j+k-mn%ADF%AA?s=www&amp;x=yyy#top/aaa <br/>
  1063. /// https://baidu.com:8080/abc/def/hi_jk-mn%ADF%AA?s=www&amp;x=yyy#top/aaa/bbb/ccc <br/>
  1064. /// http://music.163.com/#/my/m/music/empty <br/>
  1065. /// http://music.163.com/abc/#/my/m/music/empty <br/>
  1066. /// http://music.163.com/def/hhh.html?s=www&amp;x=yyy#/my/m/music/empty <br/>
  1067. /// http://music.163.com/def/hhh.html?s=www&amp;x=yyy/#/my/m/music/empty <br/>
  1068. /// http://music.163.com/#/search/m/?%23%2Fmy%2Fm%2Fmusic%2Fempty=&amp;s=fade&amp;type=1!k <br/>
  1069. /// </summary>
  1070. /// <param name="s">源字符串</param>
  1071. /// <returns>是否匹配成功</returns>
  1072. public static bool MatchUrl(this string s)
  1073. {
  1074. MatchUrl(s, out bool success);
  1075. return success;
  1076. }
  1077. #endregion
  1078. #region 权威校验身份证号码
  1079. /// <summary>
  1080. /// 根据GB11643-1999标准权威校验中国身份证号码的合法性
  1081. /// </summary>
  1082. /// <param name="s">源字符串</param>
  1083. /// <returns>是否匹配成功</returns>
  1084. public static bool MatchIdentifyCard(this string s)
  1085. {
  1086. if (s.Length == 18)
  1087. {
  1088. long n;
  1089. 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)
  1090. {
  1091. return false; //数字验证
  1092. }
  1093. string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
  1094. if (address.IndexOf(s.Remove(2), StringComparison.Ordinal) == -1)
  1095. {
  1096. return false; //省份验证
  1097. }
  1098. string birth = s.Substring(6, 8).Insert(6, "-").Insert(4, "-");
  1099. DateTime time;
  1100. if (!DateTime.TryParse(birth, out time))
  1101. {
  1102. return false; //生日验证
  1103. }
  1104. string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');
  1105. string[] wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(',');
  1106. char[] ai = s.Remove(17).ToCharArray();
  1107. int sum = 0;
  1108. for (int i = 0; i < 17; i++)
  1109. {
  1110. sum += wi[i].ToInt32() * ai[i].ToString().ToInt32();
  1111. }
  1112. int y;
  1113. Math.DivRem(sum, 11, out y);
  1114. if (arrVarifyCode[y] != s.Substring(17, 1).ToLower())
  1115. {
  1116. return false; //校验码验证
  1117. }
  1118. return true; //符合GB11643-1999标准
  1119. }
  1120. if (s.Length == 15)
  1121. {
  1122. long n;
  1123. if (long.TryParse(s, out n) == false || n < Math.Pow(10, 14))
  1124. {
  1125. return false; //数字验证
  1126. }
  1127. string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
  1128. if (address.IndexOf(s.Remove(2), StringComparison.Ordinal) == -1)
  1129. {
  1130. return false; //省份验证
  1131. }
  1132. string birth = s.Substring(6, 6).Insert(4, "-").Insert(2, "-");
  1133. DateTime time;
  1134. if (DateTime.TryParse(birth, out time) == false)
  1135. {
  1136. return false; //生日验证
  1137. }
  1138. return true;
  1139. }
  1140. return false;
  1141. }
  1142. #endregion
  1143. #region 校验IP地址的合法性
  1144. /// <summary>
  1145. /// 校验IP地址的正确性,同时支持IPv4和IPv6
  1146. /// </summary>
  1147. /// <param name="s">源字符串</param>
  1148. /// <param name="isMatch">是否匹配成功,若返回true,则会得到一个Match对象,否则为null</param>
  1149. /// <returns>匹配对象</returns>
  1150. public static Match MatchInetAddress(this string s, out bool isMatch)
  1151. {
  1152. Match match;
  1153. if (s.Contains(":"))
  1154. {
  1155. //IPv6
  1156. 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))$");
  1157. isMatch = match.Success;
  1158. }
  1159. else
  1160. {
  1161. //IPv4
  1162. match = Regex.Match(s, @"^(\d+)\.(\d+)\.(\d+)\.(\d+)$");
  1163. isMatch = match.Success;
  1164. foreach (Group m in match.Groups)
  1165. {
  1166. if (m.Value.ToInt32() < 0 || m.Value.ToInt32() > 255)
  1167. {
  1168. isMatch = false;
  1169. break;
  1170. }
  1171. }
  1172. }
  1173. return isMatch ? match : null;
  1174. }
  1175. /// <summary>
  1176. /// 校验IP地址的正确性,同时支持IPv4和IPv6
  1177. /// </summary>
  1178. /// <param name="s">源字符串</param>
  1179. /// <returns>是否匹配成功</returns>
  1180. public static bool MatchInetAddress(this string s)
  1181. {
  1182. MatchInetAddress(s, out bool success);
  1183. return success;
  1184. }
  1185. #endregion
  1186. #region 校验手机号码的正确性
  1187. /// <summary>
  1188. /// 匹配手机号码
  1189. /// </summary>
  1190. /// <param name="s">源字符串</param>
  1191. /// <param name="isMatch">是否匹配成功,若返回true,则会得到一个Match对象,否则为null</param>
  1192. /// <returns>匹配对象</returns>
  1193. public static Match MatchPhoneNumber(this string s, out bool isMatch)
  1194. {
  1195. Match match = Regex.Match(s, @"^((1[3,5,8][0-9])|(14[5,7])|(17[0,1,6,7,8])|(199))\d{8}$");
  1196. isMatch = match.Success;
  1197. return isMatch ? match : null;
  1198. }
  1199. /// <summary>
  1200. /// 匹配手机号码
  1201. /// </summary>
  1202. /// <param name="s">源字符串</param>
  1203. /// <returns>是否匹配成功</returns>
  1204. public static bool MatchPhoneNumber(this string s)
  1205. {
  1206. MatchPhoneNumber(s, out bool success);
  1207. return success;
  1208. }
  1209. #endregion
  1210. /// <summary>
  1211. /// 严格比较两个对象是否是同一对象
  1212. /// </summary>
  1213. /// <param name="_this">自己</param>
  1214. /// <param name="o">需要比较的对象</param>
  1215. /// <returns>是否同一对象</returns>
  1216. public new static bool ReferenceEquals(this object _this, object o) => object.ReferenceEquals(_this, o);
  1217. /// <summary>
  1218. /// 判断字符串是否为空
  1219. /// </summary>
  1220. /// <param name="s"></param>
  1221. /// <returns></returns>
  1222. public static bool IsNullOrEmpty(this string s) => string.IsNullOrEmpty(s);
  1223. /// <summary>
  1224. /// 类型直转
  1225. /// </summary>
  1226. /// <typeparam name="T"></typeparam>
  1227. /// <param name="value"></param>
  1228. /// <returns></returns>
  1229. public static T To<T>(this IConvertible value)
  1230. {
  1231. try
  1232. {
  1233. return (T)Convert.ChangeType(value, typeof(T));
  1234. }
  1235. catch
  1236. {
  1237. return default(T);
  1238. }
  1239. }
  1240. /// <summary>
  1241. /// 字符串转时间
  1242. /// </summary>
  1243. /// <param name="value"></param>
  1244. /// <returns></returns>
  1245. public static DateTime ToDateTime(this string value)
  1246. {
  1247. try
  1248. {
  1249. return DateTime.Parse(value);
  1250. }
  1251. catch
  1252. {
  1253. return default(DateTime);
  1254. }
  1255. }
  1256. /// <summary>
  1257. /// 字符串转Guid
  1258. /// </summary>
  1259. /// <param name="s"></param>
  1260. /// <returns></returns>
  1261. public static Guid ToGuid(this string s)
  1262. {
  1263. return Guid.Parse(s);
  1264. }
  1265. /// <summary>
  1266. /// 根据正则替换
  1267. /// </summary>
  1268. /// <param name="input"></param>
  1269. /// <param name="regex">正则表达式</param>
  1270. /// <param name="replacement">新内容</param>
  1271. /// <returns></returns>
  1272. public static string Replace(this string input, Regex regex, string replacement)
  1273. {
  1274. return regex.Replace(input, replacement);
  1275. }
  1276. /// <summary>
  1277. /// 生成唯一短字符串
  1278. /// </summary>
  1279. /// <param name="str"></param>
  1280. /// <param name="length">生成的字符串长度,越长冲突的概率越小,默认长度为10,最小长度为9,最大长度为32</param>
  1281. /// <returns></returns>
  1282. public static string CreateShortToken(this string str, int length = 10)
  1283. {
  1284. string temp = Guid.NewGuid().ToString("N").MDString();
  1285. if (length <= 32)
  1286. {
  1287. if (length < 9)
  1288. {
  1289. length = 9;
  1290. }
  1291. temp = temp.Substring(new Random().StrictNext(32 - length), length);
  1292. }
  1293. return temp;
  1294. }
  1295. /// <summary>
  1296. /// 按字段去重
  1297. /// </summary>
  1298. /// <typeparam name="TSource"></typeparam>
  1299. /// <typeparam name="TKey"></typeparam>
  1300. /// <param name="source"></param>
  1301. /// <param name="keySelector"></param>
  1302. /// <returns></returns>
  1303. public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  1304. {
  1305. HashSet<TKey> hash = new HashSet<TKey>();
  1306. return source.Where(p => hash.Add(keySelector(p)));
  1307. }
  1308. }
  1309. }