我需要根據分隔符的字符數組拆分字符串,而不是在字符串中丟失這些分隔符。即:如何在C#中使用BCL拆分不丟失分隔符的字符串?
string: "Hello world!"
separators: " !"
result: ("Hello", " ", "world", "!")
當然,我可以寫的東西,通過串去,並返回我需要的結果,但不存在的話讓我做這個東西,像神奇地配置String.Split
?
更新:我需要沒有正則表達式的解決方案,因爲它對我來說很慢。
我需要根據分隔符的字符數組拆分字符串,而不是在字符串中丟失這些分隔符。即:如何在C#中使用BCL拆分不丟失分隔符的字符串?
string: "Hello world!"
separators: " !"
result: ("Hello", " ", "world", "!")
當然,我可以寫的東西,通過串去,並返回我需要的結果,但不存在的話讓我做這個東西,像神奇地配置String.Split
?
更新:我需要沒有正則表達式的解決方案,因爲它對我來說很慢。
使用正則表達式:
string[] parts = Regex.Split(myString, yourPattern);
測試:
string[] parts = Regex.Split("Hello World!", "(!|)");
輸出:
Hello
" "//just space
World
!
""//empty string
我想你不應該使用'IgnoreCase',如果你不需要它。潛在的成本表現。另外:它確實沒有回答這個問題。 –
@phresnel:同意,修正。 –
-1再次移除。雖然OP也分裂在''。雖然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);
這將是一個純粹的程序解決方案:
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)
條件應被刪除。
一個細節:如果源字符串是「」,你會期望什麼輸出(一個空字符串和一個分隔符,或者只有一個空格)? – Groo
@Dream:我認爲使用正則表達式比使用自定義解決方案更快「如果您不傾向於使用一些不安全的上下文和指針」......而且通過使用正則表達式,您可以避免我在自定義解決方案中發生的不可預知的錯誤.. –