diff --git a/Apewer/TextUtility.cs b/Apewer/TextUtility.cs
index 5dd5fca..d5928b0 100644
--- a/Apewer/TextUtility.cs
+++ b/Apewer/TextUtility.cs
@@ -2,7 +2,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
@@ -13,17 +12,27 @@ namespace Apewer
public static class TextUtility
{
+ const string LetterChars = LowerCase + UpperCase;
const string BlankChars = " \n\r\t\f\b\a"; // 在 IsBlank 和 Trim 中视为空白的字符。
const string LineFeed = "\r\n"; // 换行符,由 ASCII 13 和 ASCII 10 组成。
- const string SpaceDbc = " ";
- const string SpaceSbc = " ";
- const string LucidChars = "3456789acefhknpstwxyz";
- const string KeyChars = "0123456789abcdefghijklmnopqrstuvwxyz";
- const string HexChars = "0123456789abcdef";
- const string NumericChars = "0123456789";
- const string LowerChars = "abcdefghijklmnopqrstuvwxyz";
- const string UpperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- const string LetterChars = LowerChars + UpperChars;
+
+ /// 半角空格。
+ public const string Space = " ";
+
+ /// 全角空格。
+ public const string SpaceSbc = " ";
+
+ /// 十进制字符。
+ public const string Decimal = "0123456789";
+
+ /// 十六进制字符。
+ public const string Hexadecimal = "0123456789abcdef";
+
+ /// 小写字母。
+ public const string LowerCase = "abcdefghijklmnopqrstuvwxyz";
+
+ /// 大写字母。
+ public const string UpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/// UTF-8 BOM。
public static byte[] Bom { get => new byte[] { 0xEF, 0xBB, 0xBF }; }
@@ -31,8 +40,11 @@ namespace Apewer
/// CRLF。
public const string CRLF = "\r\n";
+ /// CR。
+ public const char CR = '\r';
+
/// LF。
- public const string LF = "\n";
+ public const char LF = '\n';
/// 长度为 0 的空字符串。
public const string Empty = "";
@@ -220,9 +232,6 @@ namespace Apewer
return new string(output);
}
- /// 获取指定长的的空格。
- public static string Space(int length) => Duplicate(' ', length);
-
/// 将文本以转换为字节数组。默认 Encoding 为 UTF-8。
public static byte[] Bytes(string text, Encoding encoding = null)
{
@@ -650,70 +659,107 @@ namespace Apewer
public static string Random(int length, string pool = "0123456789abcdefghijklmnopqrstuvwxyz")
{
if (length < 1) return Empty;
- if (IsEmpty(pool)) return Duplicate(SpaceDbc, length);
+ if (IsEmpty(pool)) return Duplicate(Space, length);
var array = new char[length];
var max = pool.Length - 1;
for (var i = 0; i < length; i++) array[i] = pool[NumberUtility.Random(0, max)];
return new string(array);
}
- /// 对字符串列表去重。指定 valid 参数时将去除无效字符串。
- ///
- ///
- public static string[] Distinct(IEnumerable strings, bool valid = false)
+ /// 对字符串集合去重,同时去除 NULL 值和空字符串。
+ public static string[] Distinct(this IEnumerable strings) => Distinct(strings, false, false);
+
+ /// 对字符串集合去重。
+ /// 字符串集合。
+ /// 保留空字符串。
+ /// 保留 NULL 值。
+ public static string[] Distinct(this IEnumerable strings, bool withEmpty, bool withNull)
{
if (strings == null) return new string[0];
- const string space = " ";
- var hasNull = false;
- var hasEmpty = false;
- var hasSpace = false;
+ // 保留 NULL 和空字符串
+ var @null = false;
+ var empty = false;
- var array = new ArrayBuilder();
- foreach (var s in strings)
+ // 遍历,重组
+ var cache = new List();
+ if (strings is IList list)
{
- if (s == null)
- {
- if (valid) continue;
- if (hasNull) continue;
- hasNull = true;
- array.Add(s);
- continue;
- }
- if (s == Empty)
+ var count = list.Count;
+ cache.Capacity = count;
+ for (var i = 0; i < count; i++)
{
- if (valid) continue;
- if (hasEmpty) continue;
- hasEmpty = true;
- array.Add(s);
- continue;
+ var item = list[i];
+
+ if (item == null)
+ {
+ if (withNull && !@null)
+ {
+ cache.Add(item);
+ @null = true;
+ }
+ continue;
+ }
+ if (item == Empty)
+ {
+ if (withEmpty && !empty)
+ {
+ cache.Add(item);
+ empty = true;
+ }
+ continue;
+ }
+
+ var added = false;
+ for (var j = 0; j < cache.Count; j++)
+ {
+ if (cache[j] == item)
+ {
+ added = true;
+ break;
+ }
+ }
+ if (!added) cache.Add(item);
}
- if (s == space)
+ }
+ else
+ {
+ foreach (var item in strings)
{
- if (valid) continue;
- if (hasSpace) continue;
- hasSpace = true;
- array.Add(s);
- continue;
- }
+ if (item == null)
+ {
+ if (withNull && !@null)
+ {
+ cache.Add(item);
+ @null = true;
+ }
+ continue;
+ }
+ if (item == Empty)
+ {
+ if (withEmpty && !empty)
+ {
+ cache.Add(item);
+ empty = true;
+ }
+ continue;
+ }
- var exist = false;
- for (var i = 0; i < array.Length; i++)
- {
- if (array[i] == s)
+ var added = false;
+ for (var j = 0; j < cache.Count; j++)
{
- exist = true;
- break;
+ if (cache[j] == item)
+ {
+ added = true;
+ break;
+ }
}
+ if (!added) cache.Add(item);
}
- if (exist) continue;
-
- array.Add(s);
}
- return array.Export();
+ return cache.ToArray();
}
-
/// 约束字符串中的字符,只包含指定的字符。
public static string Restrict(string text, char[] chars)
{
@@ -748,7 +794,7 @@ namespace Apewer
public static string RestrictLetters(string text) => Restrict(text, LetterChars.ToCharArray());
/// 约束字符串中的字符,只包含数字。
- public static string RestrictNumeric(string text) => Restrict(text, NumericChars.ToCharArray());
+ public static string RestrictNumeric(string text) => Restrict(text, Decimal.ToCharArray());
/// 返回此字符串的安全键副本,只保留数据记录主键中可能出现的字符,默认限制长度为 255 字符。
public static string SafeKey(string text, int maxLength = 255)