假设松散的"格式",
中有一个字符串string str = "V1,B=V1,C=V1,V2,V3,D=V1,V2,A=V1,=V2,V3";
和一组已知的密钥
List<string> lst = new List<string>() { "A", "B", "C", "D" };
如何提取下面显示的键值对? (第一个键之前的任何文本都应被视为空键的值。此外,下面显示的值还删除了任何尾随逗号。)
Key Value
(null) V1
A V1,=V2,V3 (The = here is, unfortunately, part of the value)
B V1
C V1,V2,V3
D V1,V2
这个问题很难解决,因为 可能会立即在=
或,
上拆分。
答案 0 :(得分:4)
忽略已知的密钥集,并假设每个密钥只出现一次:
string str = "V1,B=V1,C=V1,V2,V3,D=V1,V2,A=V1,=V2,V3";
var splitByEqual = new[] {'='};
var values = Regex.Split(str, @",(?=\w+=)")
.Select(token => token.Split(splitByEqual, 2))
.ToDictionary(pair => pair.Length == 1 ? "" : pair.First(),
pair => pair.Last());
A=V1,V2=V3
这不起作用)V1
,B=V1
,C=V1,V2,V3
,D=V1,V2
,A=V1,=V2,V3
}。我们将其分为=
,但不超过一次。如果我们确实想要使用已知的密钥列表,我们可以将模式更改为:
var splitPattern = @",(?=(?:" + String.Join("|", keys.Select(Regex.Escape))) + ")=)";
并使用Regex.Split(str, splitPattern)
。
答案 1 :(得分:1)
假设键中没有出现键:
",|^" + KEY + "="
答案 2 :(得分:1)
在拆分之前,你不能删除前导=
吗?这是使用String.Split
和LINQ:
var pairs = str.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => new { KeyVals = x.TrimStart('=').Split('=') })
.Select(x => new
{
Key = x.KeyVals.Length == 1 ? null : x.KeyVals[0].Trim(),
Value = x.KeyVals.Last().Trim()
})
.GroupBy(x => x.Key)
.Select(g => new { g.Key, Values=g.Select(x => x.Value) });
输出:
foreach (var keyVal in pairs)
Console.WriteLine("Key:{0} Values:{1}", keyVal.Key, string.Join(",", keyVal.Values));
Key: Values:V1,V2,V3,V2,V2,V3
Key:B Values:V1
Key:C Values:V1
Key:D Values:V1
Key:A Values:V1
结果与您想要的结果不同,所以也许我走错了路。还不清楚为什么你需要“已知的一组键”。如果您想按照他们进行过滤,请在Where
之前添加GroupBy
。
答案 3 :(得分:1)
我讨厌自己去所有的老同学,但是在分裂之前尝试用另一个角色替换领先的=然后把它放回去:
private static List<KeyValuePair<string, string>> ExtractData(string dataString, List<string> keys)
{
// Convert any leading "=" to another character avoid losing it :)
dataString = dataString.Replace(",=", ",+");
List<KeyValuePair<string, string>> result = new List<KeyValuePair<string, string>>();
// Split on equals and comma
var entries = dataString.Split(new char[] { '=', ',' }, StringSplitOptions.RemoveEmptyEntries);
// Start with null key
string key = null;
// Start with blank value for each key
string value = "";
foreach (string entry in entries)
{
// Put back any removed '='
string text = entry.Replace('+', '=');
if (keys.Contains(entry))
{
// Save previous key value
if (!string.IsNullOrEmpty(value))
{
result.Add(new KeyValuePair<string, string>(key, value.TrimEnd(new char[] { ',' })));
}
key = entry;
value = "";
}
else
{
value += text + ",";
}
}
// save last result
result.Add(new KeyValuePair<string,string>(key, value.TrimEnd(new char[]{','})));
return result;
}
我知道这可以通过LINQ等缩短,但没有时间使它漂亮:)