You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

376 lines
14 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace Apewer.Internals
  5. {
  6. internal class TextModifier
  7. {
  8. /// <summary>为字符串前添加字符“0”。</summary>
  9. /// <param name="argValue">原字符串,内容应为整数、小数或十六进制数,若格式不符则返回原字符串。</param>
  10. /// <param name="argLength">新字符串的长度,若大于原数字长度,则不添加额外的“0”。</param>
  11. public static string PreZero(string argValue, int argLength = 0)
  12. {
  13. string vresult = string.IsNullOrEmpty(argValue) ? "" : Trim(argValue);
  14. if (TextVerifier.IsNumber(vresult))
  15. {
  16. if (vresult.Substring(0, 1) == ".")
  17. {
  18. vresult = "0" + vresult;
  19. }
  20. var vcc = TextGenerator.CopyChar("0", argLength - TextHelper.Len(vresult));
  21. vresult = vcc + vresult;
  22. }
  23. return vresult;
  24. }
  25. /// <summary>删除字符串前额外的字符“0”。</summary>
  26. public static string RemoveZero(string argValue)
  27. {
  28. try
  29. {
  30. string vr = Trim(argValue);
  31. while ((TextHelper.Left(vr, 1) == "0") && (TextHelper.Len(vr) > 1))
  32. {
  33. vr = TextHelper.Right(vr, TextHelper.Len(vr) - 1);
  34. }
  35. if (TextHelper.Left(vr, 1) == ".") vr = "0" + vr;
  36. return vr;
  37. }
  38. catch { return argValue; }
  39. }
  40. /// <summary>从父字符串中删除子字符串。</summary>
  41. /// <param name="argParent">父字符串。</param>
  42. /// <param name="argSub">子字符串。</param>
  43. /// <param name="argIgnoreCase">是否忽略大小写。</param>
  44. /// <returns>删除子字符串后的父字符串。</returns>
  45. public static string Exlude(string argParent, string argSub, bool argIgnoreCase = false)
  46. {
  47. if (string.IsNullOrEmpty(argParent)) return "";
  48. if (string.IsNullOrEmpty(argSub)) return argParent;
  49. try
  50. {
  51. string vp = argParent;
  52. string vs = argSub;
  53. string vr = "";
  54. int vl;
  55. int vi;
  56. if (argIgnoreCase)
  57. {
  58. vp = TextHelper.LCase(vp);
  59. vs = TextHelper.LCase(vs);
  60. }
  61. vl = vs.Length;
  62. vi = 1;
  63. while (vi <= (vp.Length - vl + 1))
  64. {
  65. if (TextHelper.Middle(vp, vi, vl) == vs)
  66. {
  67. vi = vi + vl;
  68. }
  69. else
  70. {
  71. vr = vr + TextHelper.Middle(argParent, vi, 1);
  72. vi = vi + 1;
  73. }
  74. }
  75. return vr;
  76. }
  77. catch { return argParent; }
  78. }
  79. /// <summary>替换父字符串中的子字符串。</summary>
  80. /// <param name="argParent">父字符串。</param>
  81. /// <param name="argNew">新子字符串,保留大小写。</param>
  82. /// <param name="argOld">原子字符串。</param>
  83. /// <param name="argIgnoreCase">查找时是否忽略父字符串和原子字符串大小写。</param>
  84. /// <returns>替换后的父字符串。</returns>
  85. public static string Replace(string argParent, string argOld, string argNew, bool argIgnoreCase = false)
  86. {
  87. if (string.IsNullOrEmpty(argParent)) return "";
  88. if (string.IsNullOrEmpty(argOld)) return argParent;
  89. if (string.IsNullOrEmpty(argNew)) return Exlude(argParent, argOld, argIgnoreCase);
  90. if (TextHelper.Len(argParent) < TextHelper.Len(argOld)) return argParent;
  91. if (argIgnoreCase)
  92. {
  93. try
  94. {
  95. string vparent = TextHelper.LCase(argParent);
  96. string vold = TextHelper.LCase(argOld);
  97. int vil = TextHelper.Len(argOld);
  98. int viv = 1;
  99. int vend = TextHelper.Len(argParent) - vil + 1;
  100. string vcell;
  101. string vresult = "";
  102. while (viv <= vend)
  103. {
  104. vcell = TextHelper.Middle(vparent, viv, vil);
  105. if (vcell == vold)
  106. {
  107. vresult = vresult + argNew;
  108. viv = viv + vil;
  109. }
  110. else
  111. {
  112. vresult = vresult + TextHelper.Middle(argParent, viv, 1);
  113. viv = viv + 1;
  114. }
  115. }
  116. return vresult;
  117. }
  118. catch { return argParent; }
  119. }
  120. else
  121. {
  122. try
  123. {
  124. string vresult = argParent.Replace(argOld, argNew);
  125. return vresult;
  126. }
  127. catch { return ""; }
  128. }
  129. }
  130. public static string AssureEnds(string argOrigin, bool argInclude = true, string argFoot = "\\")
  131. {
  132. if (string.IsNullOrEmpty(argOrigin)) return "";
  133. if (string.IsNullOrEmpty(argFoot)) return "";
  134. var text = argOrigin;
  135. var len = argFoot.Length;
  136. var last = text.Substring(text.Length - len, len);
  137. if (argInclude == true)
  138. {
  139. if (last != argFoot) text += argFoot;
  140. }
  141. else
  142. {
  143. while (last == argFoot)
  144. {
  145. text = text.Substring(0, text.Length - len);
  146. last = (text.Length > len) ? text.Substring(text.Length - len, len) : "";
  147. }
  148. }
  149. return text;
  150. }
  151. public static string Trim(string argOrigin, bool argIncludeSbcCase = false)
  152. {
  153. if (argOrigin == null) return Constant.EmptyString;
  154. if (argOrigin.Length < 1) return Constant.EmptyString;
  155. var result = argOrigin.Trim();
  156. if (!argIncludeSbcCase) return result;
  157. const string sbc = " ";
  158. while (true)
  159. {
  160. if (result.Length < 1) break;
  161. if (result.Equals(sbc))
  162. {
  163. result = Constant.EmptyString;
  164. break;
  165. }
  166. var left = result.Substring(0, 1);
  167. if (left.Equals(sbc))
  168. {
  169. result = result.Substring(1, result.Length - 1);
  170. continue;
  171. }
  172. var right = result.Substring(result.Length - 1, 1);
  173. if (right.Equals(sbc))
  174. {
  175. result = result.Substring(0, result.Length - 1);
  176. continue;
  177. }
  178. break;
  179. }
  180. return result;
  181. //if (argIncludeSbcCase)
  182. //{
  183. //}
  184. //if (string.IsNullOrEmpty(argOrigin)) return "";
  185. //var result = null as string;
  186. //try
  187. //{
  188. // result = argOrigin.Trim();
  189. // if (!argIncludeSbcCase) return result;
  190. //}
  191. //catch { }
  192. //try
  193. //{
  194. // if (string.IsNullOrEmpty(result)) return "";
  195. // // 前缀长度。
  196. // int left = 0;
  197. // for (int i = 0; i < result.Length; i++)
  198. // {
  199. // if (TextVerifier.IsBlank(result[i], argIncludeSbcCase)) left += 1;
  200. // else break;
  201. // }
  202. // if (left >= result.Length) return "";
  203. // // 后缀长度。
  204. // int right = 0;
  205. // for (int i = result.Length - 1; i >= left; i--)
  206. // {
  207. // if (TextVerifier.IsBlank(result[i], argIncludeSbcCase)) right += 1;
  208. // else break;
  209. // }
  210. // // 检查长度。
  211. // if (left + right <= result.Length) result = Constant.EmptyString;
  212. // return TextHelper.Middle(result, left, result.Length - left - right);
  213. //}
  214. //catch { }
  215. //return argOrigin ?? Constant.EmptyString;
  216. }
  217. /// <summary>防注入处理,去除会引发代码注入的字符,控制字符串长度(去除超出部分)。</summary>
  218. public static string AntiInject(string text, int length, IEnumerable<char> blacklist)
  219. {
  220. if (string.IsNullOrEmpty(text)) return Constant.EmptyString;
  221. if (length == 0) return Constant.EmptyString;
  222. // Trim。
  223. var output = text.Trim();
  224. if (output.Length < 1) return Constant.EmptyString;
  225. // 替换。
  226. if (blacklist != null)
  227. {
  228. foreach (var i in blacklist) output.Replace(i.ToString(), "");
  229. }
  230. // 限制长度。
  231. if (length > 0 && output.Length > length) output = output.Substring(0, length);
  232. return output;
  233. }
  234. /// <summary>剪取文本内容,若指定头部为空则从原文本首部起,若指定尾部为空则至原文本末尾。</summary>
  235. public static string Cut(string argOrigin, string argHead = null, string argFoot = null)
  236. {
  237. if (string.IsNullOrEmpty(argOrigin)) return "";
  238. if ((string.IsNullOrEmpty(argHead)) && (!string.IsNullOrEmpty(argFoot)))
  239. {
  240. var vfoot = argOrigin.IndexOf(argFoot);
  241. if (vfoot < 0) return argOrigin;
  242. var vmiddle = argOrigin.Substring(0, vfoot);
  243. return vmiddle;
  244. }
  245. if ((!string.IsNullOrEmpty(argHead)) && (string.IsNullOrEmpty(argFoot)))
  246. {
  247. var vhead = argOrigin.IndexOf(argHead) + argHead.Length;
  248. if (vhead < 0) return argOrigin;
  249. var vmiddle = argOrigin.Substring(vhead, argOrigin.Length - vhead);
  250. return vmiddle;
  251. }
  252. {
  253. var ihead = argOrigin.IndexOf(argHead) + argHead.Length;
  254. if (ihead < 0) return "";
  255. var temp = argOrigin.Substring(ihead);
  256. var ifoot = temp.IndexOf(argFoot);
  257. if (ifoot < 0) return "";
  258. var result = temp.Substring(0, ifoot);
  259. return result;
  260. }
  261. }
  262. /// <summary>限制文本长度,并去除两边的空白字符。</summary>
  263. public static string Compact(string argInput, int argLength = 0)
  264. {
  265. var text = argInput ?? "";
  266. if (text.Length > 0) text = text.Trim();
  267. if (argLength > 0 && text.Length > argLength)
  268. {
  269. text = text.Substring(0, argLength);
  270. text = text.Trim();
  271. }
  272. return text;
  273. }
  274. public static List<string> Distinct(IEnumerable<string> argOrigin, bool argValid = false)
  275. {
  276. var list = new List<string>();
  277. if (argOrigin != null)
  278. {
  279. foreach (var item in argOrigin)
  280. {
  281. var text = item;
  282. if (text == null) continue;
  283. if (argValid)
  284. {
  285. if (argValid && text != "") text = text.Trim();
  286. if (TextVerifier.IsBlank(text)) continue;
  287. }
  288. if (list.Contains(text)) continue;
  289. list.Add(text);
  290. }
  291. }
  292. return list;
  293. }
  294. /// <summary>约束字符串长度范围,超出的部分将被截取去除。</summary>
  295. public static string RestrictLength(string argOrigin, int argMaxLength)
  296. {
  297. if (argMaxLength <= 0) return Constant.EmptyString;
  298. var trim = Trim(argOrigin);
  299. if (trim.Length > argMaxLength) trim = trim.Substring(0, argMaxLength);
  300. return trim;
  301. }
  302. /// <summary>约束字符串中的字符,不允许的字符将被去除。</summary>
  303. public static string RestrictCharacters(string argOrigin, string argAllowableCharacters)
  304. {
  305. if (argOrigin == null || argOrigin.Length < 1) return "";
  306. if (argAllowableCharacters == null || argAllowableCharacters.Length < 1) return "";
  307. var sb = new StringBuilder();
  308. for (var i = 0; i < argOrigin.Length; i++)
  309. {
  310. var character = argOrigin[i];
  311. if (argAllowableCharacters.IndexOf(character) > -1) sb.Append(character);
  312. }
  313. var result = sb.ToString();
  314. #if !NET20
  315. sb.Clear();
  316. #endif
  317. return result;
  318. }
  319. /// <summary>约束字符串,只保留 GUID 可能出现的字符,根据连字符限定长度为 32 或 36,结果中字母将转换为小写。</summary>
  320. public static string RestrictGuid(string argOrigin)
  321. {
  322. if (TextVerifier.IsBlank(argOrigin)) return Constant.EmptyString;
  323. var origin = argOrigin.ToLower();
  324. var maxlength = (origin.IndexOf('-') > -1) ? 36 : 32;
  325. var result = RestrictCharacters(origin, Constant.GuidCollection);
  326. if (result.Length > maxlength) result = result.Substring(0, maxlength);
  327. return result;
  328. }
  329. }
  330. }