using Apewer.Internals; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; namespace Apewer { /// 文本实用工具。 public class TextUtility { /// UTF-8 BOM。 public static readonly byte[] Bom = Constant.Bom; /// 空文本。 public const string EmptyString = Constant.EmptyString; /// 合并为字符串。 public static string Merge(params object[] cells) => Join(null, cells); /// 合并为字符串。 public static string Merge(IEnumerable cells) => Join(null, (IEnumerable)cells); /// 合并为字符串。 public static string Join(string separator, params object[] cells) => Join(separator, (IEnumerable)cells); /// 合并为字符串。 public static string Join(string separator, IEnumerable cells) { if (cells == null) return Constant.EmptyString; var sb = new StringBuilder(); var first = true; var hasSeparator = !string.IsNullOrEmpty(separator); foreach (var cell in cells) { // if (cell == null) continue; if (!first && hasSeparator) sb.Append(separator); first = false; if (cell == null) continue; var text = (cell is string) ? (string)cell : cell.ToString(); if (string.IsNullOrEmpty(text)) continue; sb.Append(cell.ToString()); } var result = sb.ToString(); return result; } /// 重复指定子字符串,直到达到指定长度。 /// 子字符串。 /// 目标字符串的长度。 public static string CopyChar(string cell, int length) => TextGenerator.CopyChar(cell, length); /// 获取指定长的的空格。 public static string Space(int length) => TextGenerator.Space(length); /// 将文本以转换为字节数组。默认 Encoding 为 UTF-8。 public static byte[] ToBinary(string text, Encoding encoding = null) => TextConverter.ToBinary(text, encoding ?? Encoding.UTF8); /// 将字节数组转换为文本。默认 Encoding 为 UTF-8。 public static string FromBinary(byte[] bytes, Encoding encoding = null) { if (bytes == null) return Constant.EmptyString; if (bytes.LongLength < 1L) return Constant.EmptyString; try { if (encoding == null) return FromBinary(bytes, Encoding.UTF8); return encoding.GetString(bytes); } catch { return Constant.EmptyString; } } /// 将明文文本以 UTF-8 转换为 Base64 文本。 public static string ToBase64(string plain) => TextConverter.ToBase64(plain); /// 将 Base64 文本以 UTF-8 转换为明文文本。 public static string FromBase64(string cipher) => TextConverter.FromBase64(cipher); /// byte -> plain public static string EncodeByte(byte @byte) => TextConverter.EncodeByte(@byte); /// binary -> hex plain public static string EncodeBinary(byte[] bytes) { return TextConverter.EncodeBinary(bytes); } /// hex text -> plain public static string EncodeText(string text, bool delimiter = false) => TextConverter.EncodeText(text, delimiter); /// hex plain -> binary public static byte[] DecodeBinary(string plain) => TextConverter.DecodeBinary(plain); /// hex plain -> text public static string DecodeText(string plain) => TextConverter.DecodeText(plain); /// 将字节数组格式化为字符串。 public static string FormatX2(params byte[] bytes) => TextConverter.FormatX2(bytes); /// 获取单精度浮点对象。 public static Single GetFloat(char origin) => TextConverter.GetSingle(origin.ToString()); /// 获取单精度浮点对象。 public static Single GetFloat(string origin) => TextConverter.GetSingle(origin); /// 获取单精度浮点对象。 public static Single GetSingle(char origin) => TextConverter.GetSingle(origin.ToString()); /// 获取单精度浮点对象。 public static Single GetSingle(string origin) => TextConverter.GetSingle(origin); /// 获取双精度浮点对象。 public static Double GetDouble(char origin) => TextConverter.GetDouble(origin.ToString()); /// 获取双精度浮点对象。 public static Double GetDouble(string origin) => TextConverter.GetDouble(origin); /// 获取 Decimal 对象。 public static decimal GetDecimal(char origin) => TextConverter.GetDecimal(origin.ToString()); /// 获取 Decimal 对象。 public static decimal GetDecimal(string origin) => TextConverter.GetDecimal(origin); /// 获取 Int16 对象。 public static Int16 GetInt16(char origin) => TextConverter.GetInt16(origin.ToString()); /// 获取 Int16 对象。 public static Int16 GetInt16(string origin) => TextConverter.GetInt16(origin); /// 获取 Int32 对象。 public static Int32 GetInt32(char origin) => TextConverter.GetInt32(origin.ToString()); /// 获取 Int32 对象。 public static Int32 GetInt32(string origin) => TextConverter.GetInt32(origin); /// 获取 Int64 对象。 public static Int64 GetInt64(char origin) => TextConverter.GetInt64(origin.ToString()); /// 获取 Int64 对象。 public static Int64 GetInt64(string origin) => TextConverter.GetInt64(origin); /// 为字符串前添加字符“0”。 /// 原字符串,内容应为整数、小数或十六进制数,若格式不符则返回原字符串。 /// 新字符串的长度,若大于原数字长度,则不添加额外的“0”。 public static string PreZero(string origin, int length = 0) => TextModifier.PreZero(origin, length); /// 删除字符串前额外的字符“0”。 public static string RemoveZero(string text) => TextModifier.RemoveZero(text); /// 替换父字符串中的子字符串。 /// 父字符串。 /// 新子字符串,保留大小写。 /// 原子字符串。 /// 查找时是否忽略父字符串和原子字符串大小写。 /// 替换后的父字符串。 public static string Replace(string parent, string old, string @new, bool ignoreCase = false) => TextModifier.Replace(parent, old, @new, ignoreCase); /// 修复文本后缀。默认用于修复 Windows 目录路径。 /// 原文本。 /// True:追加指定后缀;False:去除指定后缀。 /// 后缀文本。 public static string AssureEnds(string origin, bool include = true, string foot = "\\") => TextModifier.AssureEnds(origin, include, foot); /// 用单字符作为分隔符拆分文本。 public static string[] Split(string text, char separator) { if (text == null) return new string[0]; if (text.Length < 1) return new string[] { "" }; if ((object)separator == null) return new string[] { text }; return text.Split(separator); } /// 用字符串作为分隔符拆分文本。 public static string[] Split(string text, string separator) { if (text == null) return new string[0]; if (text.Length < 1) return new string[] { "" }; if (string.IsNullOrEmpty(separator)) return new string[] { text }; if (separator.Length > text.Length) return new string[] { text }; var list = new List(); var position = 0; var total = text.Length; var length = separator.Length; var cell = new StringBuilder(); while (position < total) { var read = null as string; if (position + length < total) read = text.Substring(position, length); else read = text.Substring(position); if (read == separator) { if (cell.Length > 0) { list.Add(cell.ToString()); // cell.Clear(); cell = new StringBuilder(); } else { list.Add(""); } position += length; } else { cell.Append((char)text[position]); position += 1; } if (position >= total) { list.Add(cell.ToString()); } } var array = list.ToArray(); return array; } /// 用多个分隔符拆分文本。 public static string[] Split(string text, params char[] separators) { if (text == null) return new string[0]; if (text.Length < 1) return new string[] { "" }; if (separators == null || separators.Length < 1) return new string[] { text }; if (separators.Length == 1) return Split(text, separators[0]); var list = new List(); var separatorsText = new string(separators); var sb = new StringBuilder(); foreach (var c in text) { if (separatorsText.IndexOf(c) >= 0) { list.Add(sb.ToString()); //sb.Clear(); sb = new StringBuilder(); continue; } sb.Append(c); } list.Add(sb.ToString()); #if !NET20 sb.Clear(); #endif return list.ToArray(); } /// 移除字符串前后的空白。 /// 原始字符串。 public static string Trim(string origin) { return TextModifier.Trim(origin); } /// 移除字符串前后的空白。 /// 原始字符串。 /// 所有情况,全角空格将被去除。 public static string Trim(string origin, bool allCases) => TextModifier.Trim(origin, allCases); /// 防注入处理,去除会引发代码注入的字符。可限定字符串长度。 public static string AntiInject(string text, int length, params char[] blacklist) => TextModifier.AntiInject(text, length, blacklist); /// 防注入处理,去除会引发代码注入的字符。可限定字符串长度。 public static string AntiInject(string text, int length, IEnumerable blacklist) => TextModifier.AntiInject(text, length, blacklist); /// 防注入处理,去除会引发代码注入的字符。可限定字符串长度。 public static string AntiInject(string text, int length = -1, string blacklist = Constant.InjectDefaultBlackList) { return TextModifier.AntiInject(text, length, blacklist == null ? null : blacklist.ToCharArray()); } /// 剪取文本内容,若指定头部为空则从原文本首部起,若指定尾部为空则至原文本末尾。 public static string Cut(string origin, string head = null, string foot = null) => TextModifier.Cut(origin, head, foot); /// 比较两个字符串的相似度。返回值大于 0,小于等于 1。 /// /// /// public static double Similarity(string arg1, string arg2) => Levenshtein.Compute(arg1, arg2).Rate; /// 判断对象为 Null、空字符串或空白字符串。 public static bool IsEmpty(string text) => TextVerifier.IsEmpty(text); /// 判断对象为含有内容的字符串。 public static bool NotEmpty(string text) => !TextVerifier.IsEmpty(text); /// 判断对象为 Null、空字符串或无实际内容的字符串。 public static bool IsBlank(string text, bool allCases = false) => TextVerifier.IsBlank(text, allCases); /// 判断对象为含有实际内容的字符串。 public static bool NotBlank(string text, bool allCases = false) => !TextVerifier.IsBlank(text, allCases); /// 生成新的 GUID(不带连字符、小写)。 public static string NewGuid(bool hyphenation = false, bool lower = true) { var guid = Guid.NewGuid(); if (!hyphenation && lower) return guid.ToString("n"); var text = Guid.NewGuid().ToString(); if (lower) text = text.ToLower(); else text = text.ToUpper(); if (!hyphenation) text = text.Replace("-", ""); return text; } /// 生成随机字符串,出现的字符由字符池指定,默认池包含数字和字母。 /// 字符池,字符池中每个字符在随机字符串中出现的概率约等。 /// 随机字符串的长度。 public static string Random(int length, string pool = "0123456789abcdefghijklmnopqrstuvwxyz") => RandomHelper.RandomCustom(pool, length); /// 对字符串列表去重。指定 valid 参数时将去除 NULL、空字符串和空白字符串。 public static List Distinct(IEnumerable origin, bool valid = false) => TextModifier.Distinct(origin, valid); /// 约束字符串长度范围,超出的部分将被截取去除。 public static string RestrictLength(string origin, int length) => TextModifier.RestrictLength(origin, length); /// 约束字符串长度为 32,超出的部分将被截取去除。 public static string Restrict32(string origin) => TextModifier.RestrictLength(origin, 32); /// 约束字符串长度为 255,超出的部分将被截取去除。 public static string Restrict255(string origin) => TextModifier.RestrictLength(origin, 255); /// 约束字符串长度为 2000,超出的部分将被截取去除。 public static string Restrict2000(string origin) => TextModifier.RestrictLength(origin, 2000); /// 约束字符串中的字符,不允许的字符将被去除。 public static string RestrictCharacters(string origin, params char[] allowable) => TextModifier.RestrictCharacters(origin, new string(allowable)); /// 约束字符串中的字符,不允许的字符将被去除。 public static string RestrictCharacters(string origin, string allowable) => TextModifier.RestrictCharacters(origin, allowable); /// 约束字符串中的字符,只保留字母。 public static string RestrictLetters(string origin) => TextModifier.RestrictCharacters(origin, Constant.LetterCollection); /// 约束字符串中的字符,只保留数字。 public static string RestrictNumeric(string origin) => TextModifier.RestrictCharacters(origin, Constant.NumberCollection); /// 约束字符串,只保留 GUID 可能出现的字符,根据连字符限定长度为 32 或 36。 public static string RestrictGuid(string origin) => TextModifier.RestrictGuid(origin); /// 返回此字符串的安全键副本,只保留数据记录主键中可能出现的字符,默认限制长度为 255 字符。 public static string SafeKey(string text, int maxLength = 255) { if (string.IsNullOrEmpty(text)) return Constant.EmptyString; var input = ToLower(text); var max = maxLength > 0 ? maxLength : input.Length; var sb = new StringBuilder(); for (var i = 0; i < max; i++) { var c = input[i]; if (Constant.HexCollection.IndexOf(c) < 0) continue; sb.Append(c); } var result = sb.ToString(); return result; } /// 追加字符串。 public static StringBuilder Append(StringBuilder builder, params object[] cells) { if (builder != null) builder.Append(Join(null, cells)); return builder; } /// 对 URL 编码。 public static string EncodeUrl(string plain) { return UrlEncoding.Encode(plain); } /// 对 URL 解码。 public static string DecodeUrl(string escaped) { return UrlEncoding.Decode(escaped); } /// 返回此字符串转换为小写形式的副本。 public static string ToLower(string text) { if (text == null) return null; else if (text.Length < 1) return EmptyString; else return text.ToLower(); } /// 返回此字符串转换为大写形式的副本。 public static string ToUpper(string text) { if (text == null) return null; else if (text.Length < 1) return EmptyString; else return text.ToUpper(); } /// 检查中国手机号码,包含 13x、14x、15x、16x、17x、18x 和 19x 号段。 public static bool IsPhone(string phone) { if (string.IsNullOrEmpty(phone)) return false; var regex = new Regex(@"^(13|14|15|16|17|18|19)\d{9}$", RegexOptions.None); var match = regex.Match(phone); return match.Success; } /// 合并用于启动进程的参数。 public static string MergeProcessArgument(params object[] args) { // var special = " \"\n\r\b\t\f"; var list = new List(); if (args != null) { foreach (var i in args) { var arg = null as string; if (i != null) { if (i is string) arg = i as string; else arg = i.ToString(); } if (string.IsNullOrEmpty(arg)) { list.Add("\"\""); continue; } if (arg.Contains(" ") || arg.Contains("\"")) { list.Add(Merge("\"", arg.Replace("\"", "\\\""), "\"")); continue; } list.Add(arg); } } var result = Join(" ", list.ToArray()); return result; } /// 合并用于启动进程的参数。 private static string MergeProcessArgument_2(params object[] args) { if (args == null) return ""; if (args.Length < 1) return ""; var sb = new StringBuilder(); for (var i = 0; i < args.Length; i++) { if (i > 0) sb.Append(" "); var arg = null as string; if (args[i] != null) { if (args[i] is string) arg = args[i] as string; else arg = args[i].ToString(); } if (arg.IsEmpty()) { sb.Append("\"\""); continue; } // var special = " \"\n\r\b\t\f"; var special = " \""; if (arg.IndexOfAny(special.ToCharArray()) < 0) { sb.Append(arg); } else { sb.Append("\""); if (arg.NotEmpty()) { foreach (var c in arg) { switch (c) { case '"': sb.Append("\\\""); break; // case '\n': // sb.Append("\\n"); // break; // case '\r': // sb.Append("\\r"); // break; // case '\b': // sb.Append("\\b"); // break; // case '\t': // sb.Append("\\t"); // break; default: sb.Append(c); break; } } } sb.Append("\""); } } var result = sb.ToString(); return result; } } }