首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

.NET 移除字串空白字元的 10 種方法效能大比拚

     編輯:ASP.NET 基礎

前言

移除字串中所有空白字元是常見需求。但「空白」不僅是空格(U+0020),還包含製表符、換行、不間斷空格(U+00A0)、全形空格(U+3000)等 Unicode 空白字元。本文實測 10 種實作方式,從可讀度到極致效能,助你選擇最適合的方案。

空白字元定義

依 Unicode 標準,空白字元包含:Space (U+0020)、Tab (U+0009)、LF (U+000A)、VT (U+000B)、FF (U+000C)、CR (U+000D)、NEL (U+0085)、NBSP (U+00A0)、OGHAM (U+1680)、EN QUAD (U+2000)~HAIR SPACE (U+200A)、NARROW NBSP (U+202F)、MMSP (U+205F)、IDEOGRAPHIC SPACE (U+3000) 等。

10 種實作方法

方法 1:Split + Join(最直覺)

public static string TrimAllWithSplitAndJoin(string str) {
    return string.Concat(str.Split((string[])null, StringSplitOptions.RemoveEmptyEntries));
}

方法 2:LINQ Where

public static string TrimAllWithLinq(string str) {
    return new string(str.Where(c => !IsWhiteSpace(c)).ToArray());
}

方法 3:Regex 取代

static readonly Regex _ws = new Regex(@"\s+", RegexOptions.Compiled);
public static string TrimAllWithRegex(string str) {
    return _ws.Replace(str, "");
}

方法 4:字元陣列就地壓縮(推薦平衡點)

public static string TrimAllWithInplaceCharArray(string str) {
    var src = str.ToCharArray();
    int dst = 0;
    for (int i = 0; i < src.Length; i++) {
        if (!IsWhiteSpace(src[i])) src[dst++] = src[i];
    }
    return new string(src, 0, dst);
}

方法 5:字元陣列區塊複製

public static string TrimAllWithCharArrayCopy(string str) {
    var src = str.ToCharArray();
    int srcIdx = 0, dstIdx = 0, len = src.Length;
    for (int i = 0; i < len; i++) {
        if (IsWhiteSpace(src[i])) {
            int count = i - srcIdx;
            if (count > 0) Array.Copy(src, srcIdx, src, dstIdx, count);
            srcIdx = i + 1;
            dstIdx += count;
        }
    }
    if (dstIdx < len) Array.Copy(src, srcIdx, src, dstIdx, len - dstIdx);
    return new string(src, 0, len);
}

方法 6:StringBuilder 迴圈 + switch 手動判斷

public static string TrimAllWithLexerLoop(string s) {
    int len = s.Length;
    var sb = new StringBuilder(s);
    int dst = 0;
    for (int i = 0; i < s.Length; i++) {
        char ch = s[i];
        switch (ch) {
            case '\u0020': case '\u00A0': case '\u1680': case '\u2000': case '\u2001':
            case '\u2002': case '\u2003': case '\u2004': case '\u2005': case '\u2006':
            case '\u2007': case '\u2008': case '\u2009': case '\u200A': case '\u202F':
            case '\u205F': case '\u3000': case '\u2028': case '\u2029': case '\u0009':
            case '\u000A': case '\u000B': case '\u000C': case '\u000D': case '\u0085':
                len--; continue;
            default: sb[dst++] = ch; break;
        }
    }
    sb.Length = len;
    return sb.ToString();
}

方法 7:StringBuilder 迴圈 + IsWhiteSpace 呼叫

public static string TrimAllWithLexerLoopCharIsWhitespace(string s) {
    int len = s.Length;
    var sb = new StringBuilder(s);
    int dst = 0;
    for (int i = 0; i < s.Length; i++) {
        char ch = s[i];
        if (IsWhiteSpace(ch)) len--;
        else sb[dst++] = ch;
    }
    sb.Length = len;
    return sb.ToString();
}

方法 8:Unsafe 字串就地修改(不建議生產使用)

public static unsafe string TrimAllWithStringInplace(string str) {
    fixed (char* p = str) {
        char* dst = p;
        for (char* src = p; *src != '\0'; src++)
            if (!IsWhiteSpace(*src)) *dst++ = *src;
        return new string(p, 0, (int)(dst - p));
    }
}

方法 9:Unsafe 陣列索引存取

public static unsafe string TrimAllWithStringInplaceV2(string str) {
    int len = str.Length;
    fixed (char* p = str) {
        int dst = 0;
        for (int i = 0; i < len; i++)
            if (!IsWhiteSpace(p[i])) p[dst++] = p[i];
        return new string(p, 0, dst);
    }
}

方法 10:String.Replace(" ", "")(僅移除空格,非完整空白)

public static string TrimAllWithStringReplace(string str) {
    return str.Replace(" ", ""); // 功能不完整,但速度最快
}

高效能 IsWhiteSpace 實作

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsWhiteSpace(char ch) {
    switch (ch) {
        case '\u0009': case '\u000A': case '\u000B': case '\u000C': case '\u000D':
        case '\u0020': case '\u0085': case '\u00A0': case '\u1680': case '\u2000':
        case '\u2001': case '\u2002': case '\u2003': case '\u2004': case '\u2005':
        case '\u2006': case '\u2007': case '\u2008': case '\u2009': case '\u200A':
        case '\u2028': case '\u2029': case '\u202F': case '\u205F': case '\u3000':
            return true;
        default: return false;
    }
}

效能測試結果(百萬次迴圈,字串長度 100,含 20% 空白)

排名方法相對耗時備註
1String.Replace(" ", "")1.0x僅移除空格,功能不完整
2Unsafe V2 (陣列索引)1.3x需 unsafe context,破壞字串不變性
3Unsafe V1 (指標)1.4x同上
4字元陣列就地壓縮1.8x推薦:安全、快速、功能完整
5StringBuilder + switch2.1x避免方法呼叫開銷
6字元陣列區塊複製2.3x大量連續非空白時較快
7StringBuilder + IsWhiteSpace2.8x可讀性較好
8Regex (Compiled)4.5x功能強大但較慢
9LINQ Where6.2x委派開銷大
10Split + Join8.7x配置大量暫存物件

選擇建議

  • 一般應用:字元陣列就地壓縮(方法 4)——安全、快速、功能完整
  • 極致效能、可接受 unsafe:Unsafe V2(方法 9)
  • 僅需移除空格:String.Replace(" ", "")(方法 10)——最快、原生優化
  • 需支援複雜模式:Regex(方法 3)

結語

字串處理效能差異可達 10 倍。理解各方法特性,結合專案需求(功能完整度、安全性、效能)選擇最適方案。建議將 IsWhiteSpace 與 TrimAllWithInplaceCharArray 封裝為共用工具方法,專案統一使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved