2011-07-26 49 views
2

我需要根據分隔符的字符數組拆分字符串,而不是在字符串中丟失這些分隔符。即:如何在C#中使用BCL拆分不丟失分隔符的字符串?

string: "Hello world!" 
separators: " !" 
result: ("Hello", " ", "world", "!") 

當然,我可以寫的東西,通過串去,並返回我需要的結果,但不存在的話讓我做這個東西,像神奇地配置String.Split

更新:我需要沒有正則表達式的解決方案,因爲它對我來說很慢。

+0

一個細節:如果源字符串是「」,你會期望什麼輸出(一個空字符串和一個分隔符,或者只有一個空格)? – Groo

+0

@Dream:我認爲使用正則表達式比使用自定義解決方案更快「如果您不傾向於使用一些不安全的上下文和指針」......而且通過使用正則表達式,您可以避免我在自定義解決方案中發生的不可預知的錯誤.. –

回答

3

使用正則表達式:

string[] parts = Regex.Split(myString, yourPattern); 

測試:

string[] parts = Regex.Split("Hello World!", "(!|)"); 

輸出:

Hello 
" "//just space 
World 
! 
""//empty string 
+0

我想你不應該使用'IgnoreCase',如果你不需要它。潛在的成本表現。另外:它確實沒有回答這個問題。 –

+0

@phresnel:同意,修正。 –

+0

-1再次移除。雖然OP也分裂在''。雖然2它可能需要一些解釋爲什麼括號很重要。 –

2

一個LINQ溶液:

var s = "Hello world!"; 
char[] separators = { ' ', '!' }; 

string current = string.Empty; 
List<string> result = s.Aggregate(new List<string>(), (list, ch) => 
    { 
     if (separators.Contains(ch)) 
     { 
      list.Add(current); 
      list.Add(ch.ToString()); 
      current = string.Empty; 
     } 
     else current += ch; 
     return list; 
    }, list => list); 
2

這將是一個純粹的程序解決方案:

private static IEnumerable<string> Tokenize(string text, string separators) 
{ 
    int startIdx = 0; 
    int currentIdx = 0; 

    while (currentIdx < text.Length) 
    { 
     // found a separator? 
     if (separators.Contains(text[currentIdx])) 
     { 
      // yield a substring, if it's not empty 
      if (currentIdx > startIdx) 
       yield return text.Substring(startIdx, currentIdx - startIdx); 

      // yield the separator 
      yield return text.Substring(currentIdx, 1); 

      // mark the beginning of the next token 
      startIdx = currentIdx + 1; 
     } 

     currentIdx++; 
    } 
} 

請注意,此解決方案避免了返回令牌。例如,如果輸入是:

string input = "test!!"; 

主叫Tokenize(input, "!")將返回三個令牌:

test 
! 
! 

如果要求是在兩個相鄰的隔板應在它們之間具有一個空的令牌,則if (currentIdx > startIdx)條件應被刪除。

相關問題