如何将字符串拆分为字典

43

我有这个字符串

string sx="(colorIndex=3)(font.family=Helvetica)(font.bold=1)";

我正在使用“分割”的方法对其进行拆分

string [] ss=sx.Split(new char[] { '(', ')' },
    StringSplitOptions.RemoveEmptyEntries);

那么,我该如何将结果分割成一个Dictionary<string,string>呢?得到的字典应该是这样的:

Key          Value
colorIndex   3
font.family  Helvetica
font.bold    1
9个回答

85

可以使用LINQ ToDictionary()扩展方法来实现:

string s1 = "(colorIndex=3)(font.family=Helvicta)(font.bold=1)";
string[] t = s1.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries);

Dictionary<string, string> dictionary =
                      t.ToDictionary(s => s.Split('=')[0], s => s.Split('=')[1]);

编辑: 不需要两次拆分也可以达到同样的结果:

Dictionary<string, string> dictionary =
           t.Select(item => item.Split('=')).ToDictionary(s => s[0], s => s[1]);

都不知道 Split 函数可以接受字符串数组作为参数。不错。 - Arnis Lapsa
4
有没有避免调用s.Split()两次的方法? - Dmitri Nesteruk
13
当调用 t.Select(item => item.Split('=')).ToDictionary(s => s[0], s => s[1]) 时,与@erikkallen和@Luke的答案类似。 - Elisha
1
@Snickbrack,由于我完全忘记了这个答案 :) 我已经进行了编辑,现在答案包含了评论。谢谢! - Elisha

23

可能有更高效的方法,但这应该可以运行:

string sx = "(colorIndex=3)(font.family=Helvicta)(font.bold=1)";

var items = sx.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries)
    .Select(s => s.Split(new[] { '=' }));

Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (var item in items)
{
    dict.Add(item[0], item[1]);
}

19

Randal Schwartz提出了一个经验法则:当你知道需要丢弃什么时,使用split;当你知道需要保留什么时,使用正则表达式。

你知道你想要保留什么:

string sx="(colorIndex=3)(font.family=Helvetica)(font.bold=1)";

Regex pattern = new Regex(@"\((?<name>.+?)=(?<value>.+?)\)");

var d = new Dictionary<string,string>();
foreach (Match m in pattern.Matches(sx))
  d.Add(m.Groups["name"].Value, m.Groups["value"].Value);

只需要一点点的努力,你就可以使用ToDictionary实现:

var d = Enumerable.ToDictionary(
  Enumerable.Cast<Match>(pattern.Matches(sx)),
  m => m.Groups["name"].Value,
  m => m.Groups["value"].Value);

不确定这是否更美观:

var d = Enumerable.Cast<Match>(pattern.Matches(sx)).
  ToDictionary(m => m.Groups["name"].Value,
               m => m.Groups["value"].Value);

13
string sx = "(colorIndex=3)(font.family=Helvetica)(font.bold=1)";

var dict = sx.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries)
             .Select(x => x.Split('='))
             .ToDictionary(x => x[0], y => y[1]);

哦,我刚注意到这与erikkallen的答案在功能上是相同的,只是使用扩展方法语法而不是查询语法。 - LukeH
@Luke,对我来说,你的答案更易读,但这可能只是格式问题。 - Randy Levy
@Tuzo:我个人也更喜欢扩展方法语法,但我认为这完全取决于个人口味。 - LukeH
Luke,为什么dict应该是匿名类型,而不能是字典?谢谢 - Tony - TonyP
@unknown: dict 一个Dictionary<string, string>。在这种情况下,var关键字与匿名类型无关,它只是意味着编译器确定dict实际上是一个字典,并为我节省了一些打字!生成的代码与我使用Dictionary<string, string> dict等声明完全相同。http://msdn.microsoft.com/en-us/library/bb383973.aspx - LukeH

9
var dict = (from x in s1.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries)
            select new { s = x.Split('=') }).ToDictionary(x => x[0], x => x[1]);

4

通常用于HTTP查询拆分。

Usage: Dictionary<string, string> dict = stringToDictionary("userid=abc&password=xyz&retain=false");

public static Dictionary<string, string> stringToDictionary(string line, char stringSplit = '&', char keyValueSplit = '=')
{
    return line.Split(new[] { stringSplit }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Split(new[] { keyValueSplit })).ToDictionary(x => x[0], y => y[1]); ;
}

3
您可以尝试:
string sx = "(colorIndex=3)(font.family=Helvetica)(font.bold=1)";

var keyValuePairs = sx.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries)
            .Select(v => v.Split('='))
            .ToDictionary(v => v.First(), v => v.Last());

2
您可以使用正则表达式来实现这一点:
string sx = "(colorIndex=3)(font.family=Helvetica)(font.bold=1)";

Dictionary<string,string> dic = new Dictionary<string,string>();

Regex re = new Regex(@"\(([^=]+)=([^=]+)\)");

foreach(Match m in re.Matches(sx))
{
    dic.Add(m.Groups[1].Value, m.Groups[2].Value);
}

// extract values, to prove correctness of function
foreach(var s in dic)
    Console.WriteLine("{0}={1}", s.Key, s.Value);

0

我只是把这个放在这里作为参考...

对于ASP.net,如果你想将一个字符串从客户端解析成字典,这很方便...

在客户端创建一个JSON字符串,可以像这样:

var args = "{'A':'1','B':'2','C':'" + varForC + "'}";

或者像这样:

var args = JSON.stringify(new { 'A':1, 'B':2, 'C':varForC});

或者像这样:

var obj = {};
obj.A = 1;
obj.B = 2;
obj.C = varForC;
var args = JSON.stringify(obj);

将其传递到服务器... 然后在服务器端像这样解析:
 JavaScriptSerializer jss = new JavaScriptSerializer();
 Dictionary<String, String> dict = jss.Deserialize<Dictionary<String, String>>(args);

JavaScriptSerializer需要System.Web.Script.Serialization。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接