成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

.NET中刪除空白字符串的10大方法

開發(fā) 后端
我們有無數(shù)方法可用于刪除字符串中的所有空白。大部分都能夠在絕大多數(shù)的用例中很好工作,但在某些對時間敏感的應(yīng)用程序中,是否采用最快的方法可能就會造成天壤之別。

我們有無數(shù)方法可用于刪除字符串中的所有空白,但是哪個更快呢?

介紹

我們有無數(shù)方法可用于刪除字符串中的所有空白。大部分都能夠在絕大多數(shù)的用例中很好工作,但在某些對時間敏感的應(yīng)用程序中,是否采用最快的方法可能就會造成天壤之別。

如果你問空白是什么,那說起來還真是有些亂。許多人認為空白就是SPACE 字符(UnicodeU+0020,ASCII 32,HTML ),但它實際上還包括使得版式水平和垂直出現(xiàn)空格的所有字符。事實上,這是一整類定義為Unicode字符數(shù)據(jù)庫的字符。

本文所說的空白,不但指的是它的正確定義,同時也包括string.Replace(” “, “”)方法。

這里的基準方法,將刪除所有頭尾和中間的空白。這就是文章標題中“所有空白”的含義。

[[145166]]

背景

這篇文章一開始是出于我的好奇心。事實上,我并不需要用最快的算法來刪除字符串中的空白。

檢查空白字符

檢查空白字符很簡單。所有你需要的代碼就是:

 

  1. char wp = ' '
  2. char a = 'a'
  3. Assert.True(char.IsWhiteSpace(wp)); 
  4. Assert.False(char.IsWhiteSpace(a)); 
  5.  
  6. 但是,當我實現(xiàn)手動優(yōu)化刪除方法時,我意識到這并不像預期得那么好。一些源代碼在微軟的參考源代碼庫的char.cs挖掘找到: 
  7.  
  8. public static bool IsWhiteSpace(char c) { 
  9.     if (IsLatin1(c)) { 
  10.         return (IsWhiteSpaceLatin1(c)); 
  11.     } 
  12.     return CharUnicodeInfo.IsWhiteSpace(c); 
  13.  
  14. 然后CharUnicodeInfo.IsWhiteSpace成了: 
  15.  
  16. internal static bool IsWhiteSpace(char c) 
  17.     UnicodeCategory uc = GetUnicodeCategory(c); 
  18.     // In Unicode 3.0, U+2028 is the only character which is under the category "LineSeparator". 
  19.     // And U+2029 is th eonly character which is under the category "ParagraphSeparator". 
  20.     switch (uc) { 
  21.         case (UnicodeCategory.SpaceSeparator): 
  22.         case (UnicodeCategory.LineSeparator): 
  23.         case (UnicodeCategory.ParagraphSeparator): 
  24.             return (true); 
  25.     } 
  26.  
  27.     return (false); 
  28.  
  29. GetUnicodeCategory()方法調(diào)用InternalGetUnicodeCategory()方法,而且實際上相當快,但現(xiàn)在我們依次已經(jīng)有了4個方法調(diào)用!以下這段代碼是由一位評論者提供的,可用于快速實現(xiàn)定制版本和JIT默認內(nèi)聯(lián): 
  30.  
  31. // whitespace detection method: very fast, a lot faster than Char.IsWhiteSpace 
  32. [MethodImpl(MethodImplOptions.AggressiveInlining)] // if it's not inlined then it will be slow!!! 
  33. public static bool isWhiteSpace(char ch) { 
  34.     // this is surprisingly faster than the equivalent if statement 
  35.     switch (ch) { 
  36.         case '\u0009'case '\u000A'case '\u000B'case '\u000C'case '\u000D'
  37.         case '\u0020'case '\u0085'case '\u00A0'case '\u1680'case '\u2000'
  38.         case '\u2001'case '\u2002'case '\u2003'case '\u2004'case '\u2005'
  39.         case '\u2006'case '\u2007'case '\u2008'case '\u2009'case '\u200A'
  40.         case '\u2028'case '\u2029'case '\u202F'case '\u205F'case '\u3000'
  41.             return true
  42.         default
  43.             return false
  44.     } 

刪除字符串的不同方法

我用各種不同的方法來實現(xiàn)刪除字符串中的所有空白。

分離合并法

這是我一直在用的一個非常簡單的方法。根據(jù)空格字符分離字符串,但不包括空項,然后將產(chǎn)生的碎片重新合并到一起。這方法聽上去有點傻乎乎的,而事實上,乍一看,很像是一個非常浪費的解決方式:

 

  1. public static string TrimAllWithSplitAndJoin(string str) { 
  2.     return string.Concat(str.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries)); 
  3.  
  4. LINQ 
  5.  
  6. 這是優(yōu)雅地聲明式地實現(xiàn)這個過程的方法: 
  7.  
  8. public static string TrimAllWithLinq(string str) { 
  9.     return new string(str.Where(c => !isWhiteSpace(c)).ToArray()); 

正則表達式

正則表達式是非常強大的力量,任何程序員都應(yīng)該意識到這一點。

 

  1. static Regex whitespace = new Regex(@"\s+", RegexOptions.Compiled); 
  2.  
  3. public static string TrimAllWithRegex(string str) { 
  4.     return whitespace.Replace(str, ""); 

字符數(shù)組原地轉(zhuǎn)換法

該方法將輸入的字符串轉(zhuǎn)換成字符數(shù)組,然后原地掃描字符串去除空白字符(不創(chuàng)建中間緩沖區(qū)或字符串)。***,經(jīng)過“刪減”的數(shù)組會產(chǎn)生新的字符串。

 

  1. public static string TrimAllWithInplaceCharArray(string str) { 
  2.     var len = str.Length; 
  3.     var src = str.ToCharArray(); 
  4.     int dstIdx = 0
  5.     for (int i = 0; i < len; i++) { 
  6.         var ch = src[i]; 
  7.         if (!isWhiteSpace(ch)) 
  8.             src[dstIdx++] = ch; 
  9.     } 
  10.     return new string(src, 0, dstIdx); 

字符數(shù)組復制法

這種方法類似于字符數(shù)組原地轉(zhuǎn)換法,但它使用Array.Copy復制連續(xù)非空白“字符串”的同時跳過空格。***,它將創(chuàng)建一個適當尺寸的字符數(shù)組,并用相同的方式返回一個新的字符串。

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

循環(huán)交換法

用代碼實現(xiàn)循環(huán),并使用StringBuilder類,通過依靠StringBuilder的內(nèi)在優(yōu)化來創(chuàng)建新的字符串。為了避免任何其他因素對本實施產(chǎn)生干擾,不調(diào)用其他的方法,并且通過緩存到本地變量避免訪問類成員。***通過設(shè)置StringBuilder.Length將緩沖區(qū)調(diào)整到合適大小。

// Code suggested by http://www.codeproject.com/Members/TheBasketcaseSoftware
public static string TrimAllWithLexerLoop(string s) {
    int length = s.Length;
    var buffer = new StringBuilder(s);
    var dstIdx = 0;
    for (int index = 0; index < s.Length; index++) {
        char ch = s[index];
        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':
                length--;
                continue;
            default:
                break;
        }
        buffer[dstIdx++] = ch;
    }
    buffer.Length = length;
    return buffer.ToString();;
}

循環(huán)字符法

這種方法幾乎和前面的循環(huán)交換法相同,不過它采用if語句來調(diào)用isWhiteSpace(),而不是亂七八糟的switch伎倆 :)。

public static string TrimAllWithLexerLoopCharIsWhitespce(string s) {
    int length = s.Length;
    var buffer = new StringBuilder(s);
    var dstIdx = 0;
    for (int index = 0; index < s.Length; index++) {
        char currentchar = s[index];
        if (isWhiteSpace(currentchar))
            length--;
        else
            buffer[dstIdx++] = currentchar;
    }
    buffer.Length = length;
    return buffer.ToString();;
}

原地改變字符串法(不安全)

這種方法使用不安全的字符指針和指針運算來原地改變字符串。我不推薦這個方法,因為它打破了.NET框架在生產(chǎn)中的基本約定:字符串是不可變的。

public static unsafe string TrimAllWithStringInplace(string str) {
    fixed (char* pfixed = str) {
        char* dst = pfixed;
        for (char* p = pfixed; *p != 0; p++)
            if (!isWhiteSpace(*p))
                *dst++ = *p;

        /*// reset the string size
            * ONLY IT DIDN'T WORK! A GARBAGE COLLECTION ACCESS VIOLATION OCCURRED AFTER USING IT
            * SO I HAD TO RESORT TO RETURN A NEW STRING INSTEAD, WITH ONLY THE PERTINENT BYTES
            * IT WOULD BE A LOT FASTER IF IT DID WORK THOUGH...
        Int32 len = (Int32)(dst - pfixed);
        Int32* pi = (Int32*)pfixed;
        pi[-1] = len;
        pfixed[len] = '\0';*/
        return new string(pfixed, 0, (int)(dst - pfixed));
    }
}

原地改變字符串法V2(不安全)

這種方法幾乎和前面那個相同,不過此處使用類似數(shù)組的指針訪問。我很好奇,不知道這兩種哪種存儲訪問會更快。

public static unsafe string TrimAllWithStringInplaceV2(string str) {
    var len = str.Length;
    fixed (char* pStr = str) {
        int dstIdx = 0;
        for (int i = 0; i < len; i++)
            if (!isWhiteSpace(pStr[i]))
                pStr[dstIdx++] = pStr[i];
        // since the unsafe string length reset didn't work we need to resort to this slower compromise
        return new string(pStr, 0, dstIdx);
    }
}

String.Replace(“”,“”)

這種實現(xiàn)方法很天真,由于它只替換空格字符,所以它不使用空白的正確定義,因此會遺漏很多其他的空格字符。雖然它應(yīng)該算是本文中最快的方法,但功能不及其他。

但如果你只需要去掉真正的空格字符,那就很難用純.NET寫出勝過string.Replace的代碼。大多數(shù)字符串方法將回退到手動優(yōu)化本地C ++代碼。而String.Replace本身將用comstring.cpp調(diào)用C ++方法:

FCIMPL3(Object*,
    COMString::ReplaceString,
    StringObject* thisRefUNSAFE,
    StringObject* oldValueUNSAFE,
    StringObject* newValueUNSAFE)

下面是基準測試套件方法:

public static string TrimAllWithStringReplace(string str) {
    // This method is NOT functionaly equivalent to the others as it will only trim "spaces"
    // Whitespace comprises lots of other characters
    return str.Replace(" ", "");
}

許可證

這篇文章,以及任何相關(guān)的源代碼和文件,依據(jù)The Code Project Open License (CPOL)的許可。

 

 

 

譯文鏈接:http://www.codeceo.com/article/donet-remove-whitespace-string.html
英文原文:Fastest method to remove all whitespace from Strings in .NET

 

責任編輯:王雪燕 來源: 碼農(nóng)網(wǎng)
相關(guān)推薦

2015-10-29 11:55:30

.NET空白字符串方法

2020-09-07 13:08:36

String空白字符方式

2009-07-24 13:01:44

ASP.NET頁面跳轉(zhuǎn)

2010-11-25 15:59:33

字符串.NET

2025-05-21 04:00:00

JavaScript前端

2020-09-03 10:13:49

JavaScript字符串pad

2009-07-06 13:18:35

Servlet方法

2010-05-07 08:59:50

ASP.NET

2009-07-28 10:36:37

ASP.NET讀取Ex

2013-07-15 11:00:18

提升WI-FI信號強度

2010-01-13 15:12:04

VB.NET字符串合并

2010-06-21 09:48:43

2024-04-01 08:41:39

字符串.NET

2009-07-24 10:06:33

數(shù)據(jù)庫字符串ASP.NET

2020-05-14 10:24:41

YAML配置字符串

2021-05-18 09:08:18

字符串子串對象

2009-11-26 18:28:07

PHP函數(shù)trim()

2020-10-16 18:35:53

JavaScript字符串正則表達式

2024-06-11 07:34:58

C#字符串性能

2019-12-10 10:31:30

javascriptWeb前端開發(fā)
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久久精 | 久草色播| 亚洲精品9999 | 国产性网| 中文字幕视频一区二区 | 午夜视频在线播放 | 亚洲成色777777在线观看影院 | 国产玖玖 | 精品熟人一区二区三区四区 | 日本午夜一区二区三区 | 国产精品乱码一二三区的特点 | 精品国产一区二区三区久久久蜜月 | 日韩精品免费视频 | 精品国产一区二区三区久久影院 | 午夜一区| 91亚洲国产成人久久精品网站 | 免费在线观看成人 | 玖玖国产精品视频 | 欧美一区二区三区在线 | 91视频网 | 成人av资源在线 | 中文字幕视频在线看5 | 色在线看| 日本激情视频中文字幕 | 国产高清一二三区 | 成人在线h | 亚洲视频一区二区 | 亚洲欧美激情网 | 97国产一区二区 | 日韩精品免费在线 | 精品国产乱码久久久久久88av | 免费在线观看毛片 | 亚洲精品9999 | 日本一区二区三区在线观看 | 国产韩国精品一区二区三区 | 精品国产免费一区二区三区演员表 | 欧美精品综合 | 国产精品美女久久久久久久网站 | 丁香综合 | 少妇诱惑av | 国产成人aⅴ |