我有以下字符串
MyKey1=MyVal1
MyKey2=MyVal2
MyKey3=MyVal3
MyKey3=MyVal3
首先,需要分割成行,然后我需要将每一行拆分为“=
”字符来获取该行的键和值。因此,我想要的是List<KeyValuePair<string, string>>
(为什么不是Dictionary
?=&gt;列表中可能有重复的键),所以我无法使用.ToDictionary()
扩展
我非常坚持以下内容:
List<KeyValuePair<string, string>> fields =
(from lines in Regex.Split(input, @"\r?\n|\r", RegexOptions.None)
where !String.IsNullOrWhiteSpace(lines)
.Select(x => x.Split(new [] { '='}, 2, StringSplitOptions.RemoveEmptyEntries))
.ToList()
--> select new KeyValuePair? Or with 'let' for splitting by '='?
what about exception handling (e.g. ignoring empty values)
答案 0 :(得分:2)
如果您担心重复的密钥,可以使用ILookup
代替:
var fields =
(from line in Regex.Split(input, @"\r?\n|\r", RegexOptions.None)
select line.Split(new [] { '=' }, 2))
.ToLookup(x => x[0], x => x[1]);
var items = fields["MyKey3"]; // [ "MyVal3", "MyVal3" ]
答案 1 :(得分:2)
您可以使用Lookup<TKey, TValue>
代替词典:
var keyValLookup = text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Select(l =>
{
var keyVal = l.Split('=');
return new { Key = keyVal[0].Trim(), Value = keyVal.ElementAtOrDefault(1) };
})
.Where(x => x.Key.Length > 0) // not required, just to show how to handle invalid data
.ToLookup(x => x.Key, x => x.Value);
IEnumerable<string> values = keyValLookup["MyKey3"];
Console.Write(string.Join(", ",values)); // MyVal3, MyVal3
即使密钥不存在,查找也始终返回值。然后它是一个空序列。密钥不能是唯一的,因此在使用ToLookup
之前,您无需分组或删除重复项。
答案 2 :(得分:1)
你非常接近(我将你的例子改为所有方法语法以保持一致性):
List<KeyValuePair<string, string>> fields =
Regex.Split(input, @"\r?\n|\r", RegexOptions.None)
.Where(s => !String.IsNullOrWhiteSpace(s))
.Select(x => x.Split(new [] {'='}, 2, StringSplitOptions.RemoveEmptyEntries)
.Where(p => p.Length == 2) // to avoid IndexOutOfRangeException
.Select(p => new KeyValuePair(p[0], p[1]));
虽然我同意Jon的评论,如果你有重复的密钥,分组会更清晰:
IEnumerable<IGrouping<string, string>> fields =
Regex.Split(input, @"\r?\n|\r", RegexOptions.None)
.Where(s => !String.IsNullOrWhiteSpace(s))
.Select(x => x.Split(new [] {'='}, 2, StringSplitOptions.RemoveEmptyEntries))
.GroupBy(p => p[0]);
答案 3 :(得分:0)
我建议您尝试匹配键/值而不是分割。如果您想要一个包含多个键值的词典,可以使用ToLookup
(ILookup
}:
var result = Regex.Matches(input, @"(?<key>[^=\r\n]+)=(?<value>[^=\r\n]+)")
.OfType<Match>()
.ToLookup(m => m.Groups["key"].Value,
m => m.Groups["value"].Value);
如果您稍后需要添加到该列表或想要继续使用列表:
var result = Regex.Matches(input, @"(?<key>[^=\r\n]+)=(?<value>[^=\r\n]+)")
.OfType<Match>()
.Select(m => new KeyValuePair<string, string>(m.Groups["key"].Value, m.Groups["value"].Value))
.ToList();
注意:使用的正则表达式可能不适合您的用途,因为我们不知道您可能有的输入。