我正在解析一些分隔符分隔的值,其中
?
被指定为转义字符,以防分隔符作为其中一个值的一部分出现。
例如:如果
:
是分隔符,某个字段的值为19:30
,则需要写为19?:30
。
目前,我使用
string[] values = input.Split(':');
来获取所有值的数组,但是在了解了这个转义字符之后,这将不再起作用。
有没有办法让
Split
考虑转义字符?我检查了重载方法,好像没有直接这样的选项
string[] substrings = Regex.Split("aa:bb:00?:99:zz", @"(?<!\?):");
对于
aa
bb
00?:99
zz
或者您可能想要取消转义?:在某些时候,用另一个标记替换输入中的序列,拆分并替换回来。
(这需要使用
System.Text.RegularExpressions
命名空间。)
这种东西在不使用 Regex 的情况下编码总是很有趣。
下面的方法可以解决一个问题:转义字符将always转义,它没有逻辑来仅检查valid:
?;
。因此字符串 one?two;three??;four?;five
将被拆分为 onewo
、three?
、fourfive
。
public static IEnumerable<string> Split(this string text, char separator, char escapeCharacter, bool removeEmptyEntries)
{
string buffer = string.Empty;
bool escape = false;
foreach (var c in text)
{
if (!escape && c == separator)
{
if (!removeEmptyEntries || buffer.Length > 0)
{
yield return buffer;
}
buffer = string.Empty;
}
else
{
if (c == escapeCharacter)
{
escape = !escape;
if (!escape)
{
buffer = string.Concat(buffer, c);
}
}
else
{
if (!escape)
{
buffer = string.Concat(buffer, c);
}
escape = false;
}
}
}
if (buffer.Length != 0)
{
yield return buffer;
}
}
基于InBetween的回答。使用 StringBuilder。并确保它包含直接在转义字符之后出现的任何字符,而不是删除它。
public static IEnumerable<string> Split(this string text, char separator, char escapeCharacter, bool removeEmptyEntries)
{
var buffer = new StringBuilder();
bool escape = false;
foreach (var c in text)
{
if (!escape && c == separator)
{
if (!removeEmptyEntries || buffer.Length > 0)
{
yield return buffer.ToString();
}
buffer.Clear();
}
else
{
if (c == escapeCharacter && !escape)
{
escape = true;
}
else
{
buffer.Append(c);
escape = false;
}
}
}
if (buffer.Length != 0)
{
yield return buffer.ToString();
}
}
这意味着
Split("aa:bb:00?:99:zz", ':', '?', false);
为您提供:
aa
bb
00:99
zz
和
Split("Comma here:\\,,no comma:,slash:\\\\,slash and comma:\\\\\\,", ',', '\\', false);
为您提供:
Comma here:,
no comma:
slash:\
slash and comma:\,
不,没有办法做到这一点。您将需要使用正则表达式(这取决于您希望“转义字符”的行为方式)。在最坏的情况下,我想你必须手动进行解析。