1

我有以下字符串

 MyKey1=MyVal1
 MyKey2=MyVal2
 MyKey3=MyVal3
 MyKey3=MyVal3

所以首先,需要拆分成行,然后我需要用 ' =' char 拆分每一行以从该行获取键和值。因此,我想要的是一个List<KeyValuePair<string, string>>(为什么不是Dictionary? => 列表中可能有重复的键),所以我不能使用.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)
4

4 回答 4

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" ]
于 2013-07-16T12:49:58.380 回答
2

您可以使用 aLookup<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

于 2013-07-16T12:53:38.980 回答
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]);
于 2013-07-16T12:50:14.317 回答
0

我建议您尝试匹配键/值而不是拆分。如果您想要一个包含多个键值的字典,您可以使用ToLookup(an 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();

注意:使用的正则表达式可能不适合您的用途,因为我们不知道您可能拥有的输入。

于 2013-07-16T12:53:45.963 回答