你也可以不使用正则表达式来实现这个功能。下面的扩展方法允许你指定分隔符和一个开始和结束转义序列的字符。请注意,它不验证所有的转义序列是否都被关闭。
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 = "\"one@tw;,.'o\"@hotmail.com;\"some;thing\"@example.com;hello@world;\"D;D@blah;blah.com\"";
foreach (var address in input.SpecialSplit(';', '"'))
Console.WriteLine(v);
给出以下输出结果:
"one@tw;,.'o"@hotmail.com
"some;thing"@example.com
hello@world
"D;D@blah;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;thing@example.com”)。否则,请查找其他分隔符字符,例如管道|
。 - code_dredd(^|;)(.*?)@([\d\w]+[-]*)+\.\w+
- Camo;
字符,而它在电子邮件地址中是有效的。 - Jamie Rees