你也可以做到這一點,而無需使用正則表達式。下面的擴展方法將允許你指定一個分隔字符和一個字符來開始和結束轉義序列。請注意,它不驗證所有轉義序列都已關閉。
public static IEnumerable<string> SpecialSplit(
this string str, char delimiter, char beginEndEscape)
{
int beginIndex = 0;
int length = 0;
bool escaped = false;
foreach (char c in str)
{
if (c == beginEndEscape)
{
escaped = !escaped;
}
if (!escaped && c == delimiter)
{
yield return str.Substring(beginIndex, length);
beginIndex += length + 1;
length = 0;
continue;
}
length++;
}
yield return str.Substring(beginIndex, length);
}
那麼下面
var input = "\"[email protected];,.'o\"@hotmail.com;\"some;thing\"@example.com;[email protected];\"D;[email protected];blah.com\"";
foreach (var address in input.SpecialSplit(';', '"'))
Console.WriteLine(v);
雖然給這個輸出
"[email protected];,.'o"@hotmail.com
「一些;事」 @ example.com
hello @ world
「d; d @等等; blah.com」
下面是一個額外的單轉義字符工作的版本。它假設兩個連續的轉義字符應該成爲一個單一的轉義字符,並且它同時逃脫了兩個beginEndEscape
章程,所以它不會觸發轉義序列的開始或結束,它也會轉義delimiter
。轉義字符後面的任何其他內容都將與轉義字符一起被刪除。
public static IEnumerable<string> SpecialSplit(
this string str, char delimiter, char beginEndEscape, char singleEscape)
{
StringBuilder builder = new StringBuilder();
bool escapedSequence = false;
bool previousEscapeChar = false;
foreach (char c in str)
{
if (c == singleEscape && !previousEscapeChar)
{
previousEscapeChar = true;
continue;
}
if (c == beginEndEscape && !previousEscapeChar)
{
escapedSequence = !escapedSequence;
}
if (!escapedSequence && !previousEscapeChar && c == delimiter)
{
yield return builder.ToString();
builder.Clear();
continue;
}
builder.Append(c);
previousEscapeChar = false;
}
yield return builder.ToString();
}
最後你應該添加null
檢查傳遞進來,請注意,這兩個將返回一個序列與一個空字符串,如果你在一個空字符串傳遞字符串。
我的建議是,以確保您的分隔符不顯示任何其他地方以外,以紀念邊界在電子郵件之間,所以不應該允許帶'''的電子郵件作爲他們名字的一部分(例如「some; [email protected]」)。否則,找到一個不同的分隔符,如管道'|'? – ray
正規救援?也許你可以適應:http://stackoverflow.com/questions/7430186/regex-split-string-with-on-a-delimetersemi-colon-except-those-that-appear-in – Corak
嘗試以下方法:'(^ |;)(。*?)@([\ d \ w] + [ - ] *)+ \。\ w +' – Camo