在這裏,你可以使用任何順序的分隔符組合,也可以在字符串中找不到分隔符。我花了一段時間纔想出來,發佈後,它看起來比其他答案更復雜!
好吧,無論如何我都會把它放在這裏。
public static string SplitAndReJoin(string str, char[] delimiters,
Func<string[], string[]> mutator)
{
//first thing to know is which of the delimiters are
//actually in the string, and in what order
//Using ToArray() here to get the total count of found delimiters
var delimitersInOrder = (from ci in
(from c in delimiters
from i in FindIndexesOfAll(str, c)
select new { c, i })
orderby ci.i
select ci.c).ToArray();
if (delimitersInOrder.Length == 0)
return str;
//now split and mutate the string
string[] strings = str.Split(delimiters);
strings = mutator(strings);
//now build a format string
//note - this operation is much more complicated if you wish to use
//StringSplitOptions.RemoveEmptyEntries
string formatStr = string.Join("",
delimitersInOrder.Select((c, i) => string.Format("{{{0}}}", i)
+ c));
//deals with the 'perfect' split - i.e. there's always two values
//either side of a delimiter
if (strings.Length > delimitersInOrder.Length)
formatStr += string.Format("{{{0}}}", strings.Length - 1);
return string.Format(formatStr, strings);
}
public static IEnumerable<int> FindIndexesOfAll(string str, char c)
{
int startIndex = 0;
int lastIndex = -1;
while(true)
{
lastIndex = str.IndexOf(c, startIndex);
if (lastIndex != -1)
{
yield return lastIndex;
startIndex = lastIndex + 1;
}
else
yield break;
}
}
而且這裏有一個測試,你可以用它來驗證它:
[TestMethod]
public void TestSplitAndReJoin()
{
//note - mutator does nothing
Assert.AreEqual("a,b", SplitAndReJoin("a,b", ",".ToCharArray(), s => s));
//insert a 'z' in front of every sub string.
Assert.AreEqual("zaaa,zbbbb.zccc|zdddd:zeee", SplitAndReJoin("aaa,bbbb.ccc|dddd:eee",
",.|:".ToCharArray(), s => s.Select(ss => "z" + ss).ToArray()));
//re-ordering of delimiters + mutate
Assert.AreEqual("zaaa,zbbbb.zccc|zdddd:zeee", SplitAndReJoin("aaa,bbbb.ccc|dddd:eee",
":|.,".ToCharArray(), s => s.Select(ss => "z" + ss).ToArray()));
//now how about leading or trailing results?
Assert.AreEqual("a,", SplitAndReJoin("a,", ",".ToCharArray(), s => s));
Assert.AreEqual(",b", SplitAndReJoin(",b", ",".ToCharArray(), s => s));
}
請注意,我假設你需要能夠做一些與數組中的元素,控制單個再次將它們重新組合在一起之前的字符串 - 否則可能你只會保留原始字符串!
該方法構建一個動態格式字符串。這裏沒有保修效率:)
我認爲你可能需要手動完成。 – Jason
是否總是以完全相同的順序排列? –
看看http://stackoverflow.com/questions/2910536/regex-split-string-but-keep-separators看看是否有幫助。 –