0

我正在尝试解析一个字符串并构建一个字典,该字典将包含字段的名称及其作为键/值的值。

这是代码:

var dictPriceList = Regex.Matches(priceListToParse, @"""(.+?) - \$([\d.]+)").Cast<Match>()
                                         .ToDictionary(x => x.Groups[1].Value,
                                                       x => x.Groups[2].Value);

这是我需要解析的字符串示例:

var results = 
[{\r\n\t\"bandanaColor\": \"rgb(0,0,255)\",\r\n    \"ninja\": \"Leonardo - $0.99\",\r\n    \"data\": [[1336485655241,0.99],[1336566333236,0.99],[1336679536073,0.99],[1336706394834,0.99],[1336774593068,0.99],[1366284992043,0.99]]},
\r\n{\r\n\t\"bandanaColor\": \"rgb(128,0,128)\",\r\n    \"ninja\": \"Donatello - $0.25\",\r\n    \"data\": [[1361061084420,0.23],[1366102471587,0.25],[1366226367262,0.25],[1366284992043,0.25]]},
\r\n{\r\n\t\"bandanaColor\": \"rgb(255,0,0)\",\r\n    \"ninja\": \"Raphael - $0.15\",\r\n    \"data\": [[1327305600000,0.15], [1365583220422,0.15],[1365669396241,0.15],[1365669396241,0.15],[1365753433493,0.15],[1366284992043,0.15]]},\r\n\
r\n{\r\n\t\"bandanaColor\": \"rgb(255,165,0)\",\r\n    \"ninja\": \"Michelangelo - $0.14\",\r\n    \"data\": [1366284992043,0.14]};

在这里,我需要的唯一值是标签“ninja”和“Leonardo - 0.99 美元”。所以我最终会得到这些值:

核心价值

莱昂纳多 \ 0.99

多纳泰罗 \ 0.25

拉斐尔 \ 0.15

米开朗基罗 \ 0.14

好的,我已经尝试过这个问题并得到了大家的帮助,我很感激,但从那以后我没有机会尝试我的手。但从那时起,该t\"bandanaColor\": \"rgb(0,0,255)\",行被添加,我需要忽略它,因为它与我想做的事情无关。现在这条线崩溃了,我认为,因为这条线。

谁能帮我弄清楚如何得到我想要的东西?

编辑

当代码到达正则表达式行时,这是我获得的崩溃:

An item with the same key has already been added.

4

1 回答 1

1

好的,首先你提供的 JSON 有一些错误。假设这只是创建问题并且没有更大的问题,最终结果应该类似于:

[{\"bandanaColor\":\"rgb(0,0,255)\",\"ninja\":\"Leonardo - $0.99\",\"data\":[[1336485655241,0.99],[1336566333236,0.99 ],[1336679536073,0.99],[1336706394834,0.99],[1336774593068,0.99],[1366284992043,0.99]]},{\"bandanaColor\":\"rgb(128,0,128)\",\"ninja\ ":\"Donatello - $0.25\",\"data\":[[1361061084420,0.23],[1366102471587,0.25],[1366226367262,0.25],[1366284992043,0.25]]},{\"bandanaColor\": \"rgb(255,0,0)\",\"ninja\":\"Raphael - $0.15\",\"data\":[[1327305600000,0.15],[1365583220422,0.15],[1365669396241,0.15 ],[1365669396241,0.15],[1365753433493,0.15],[1366284992043,0.15]]},{\"bandanaColor\":\"rgb(255,165,0)\",\"ninja\":\"Michelangelo - $0.14\",\"数据\":[1366284992043,0.14]}]

(可以使用这样的网站进行测试

现在,就解析而言,Regex 将是有问题的。JSON有很多不同的障碍,所以解析器将是最好的选择。而且,为了避免重新发明轮子,这个Json.NET库恰好运行得非常好。举个例子:

/* includes
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
*/

// the original JSON string
String jsonString = "[{\"bandanaColor\":\"rgb(0,0,255)\",\"ninja\":\"Leonardo - $0.99\",\"data\":[[1336485655241,0.99],[1336566333236,0.99],[1336679536073,0.99],[1336706394834,0.99],[1336774593068,0.99],[1366284992043,0.99]]},{\"bandanaColor\":\"rgb(128,0,128)\",\"ninja\":\"Donatello - $0.25\",\"data\":[[1361061084420,0.23],[1366102471587,0.25],[1366226367262,0.25],[1366284992043,0.25]]},{\"bandanaColor\":\"rgb(255,0,0)\",\"ninja\":\"Raphael - $0.15\",\"data\":[[1327305600000,0.15],[1365583220422,0.15],[1365669396241,0.15],[1365669396241,0.15],[1365753433493,0.15],[1366284992043,0.15]]},{\"bandanaColor\":\"rgb(255,165,0)\",\"ninja\":\"Michelangelo - $0.14\",\"data\":[1366284992043,0.14]}]";
// The parsed result (using Json.NET)
var json = JsonConvert.DeserializeObject(jsonString);
// Grab all the "ninjas"
String[] ninjas = (json as JArray).Select (x => x.Value<String>("ninja")).ToArray();
// Begin aggregating the results
IDictionary<String, Double> result = ninjas.ToDictionary(
    x => x.Substring(0, x.IndexOf(" - ")),
    y => {
        Double d;
        return Double.TryParse(y.Substring(y.IndexOf(" - ") + 4), out d) ? d : default(Double);
    }
);

给你:

Key           Value
Leonardo      0.99 
Donatello     0.25 
Raphael       0.15 
Michelangelo  0.14 

我使用了简单的字符串解析(由 的实例分割-),但如有必要,您可以得到更详细的信息。


第二版

多一点投资时间(因为您没有创建对象),但回报是您不必学习处理 JObject、JArray 等的 Json 语法。相反,它将数据序列化到类中(您've created) 使检索信息更加流畅。例如

public class ParentObj
{
    public String bandanaColor;
    public String ninja;

    public String NinjaName
    {
        get
        {
            String ninja = this.ninja ?? String.Empty;
            Int32 i = ninja.IndexOf(" - ");
            return i != -1 ? ninja.Substring(0, i) : String.Empty;
        }
    }
    public Double NinjaPrice
    {
        get
        {
            String ninja = this.ninja ?? String.Empty;
            Double price;
            Int32 i = ninja.IndexOf(" - $");
            return i != -1 && Double.TryParse(ninja.Substring(i + 4), out price) ? price : default(Double);
        }
    }
}

void Main()
{
    // the original JSON string
    String jsonString = "[{\"bandanaColor\":\"rgb(0,0,255)\",\"ninja\":\"Leonardo - $0.99\",\"data\":[[1336485655241,0.99],[1336566333236,0.99],[1336679536073,0.99],[1336706394834,0.99],[1336774593068,0.99],[1366284992043,0.99]]},{\"bandanaColor\":\"rgb(128,0,128)\",\"ninja\":\"Donatello - $0.25\",\"data\":[[1361061084420,0.23],[1366102471587,0.25],[1366226367262,0.25],[1366284992043,0.25]]},{\"bandanaColor\":\"rgb(255,0,0)\",\"ninja\":\"Raphael - $0.15\",\"data\":[[1327305600000,0.15],[1365583220422,0.15],[1365669396241,0.15],[1365669396241,0.15],[1365753433493,0.15],[1366284992043,0.15]]},{\"bandanaColor\":\"rgb(255,165,0)\",\"ninja\":\"Michelangelo - $0.14\",\"data\":[1366284992043,0.14]}];";
    // The parsed result (using Json.NET in to our custom object)
    IEnumerable<ParentObj> json = JsonConvert.DeserializeObject<IEnumerable<ParentObj>>(jsonString.TrimEnd(';'));
    // the use Linq to create a dictionary from our custom getters
    IDictionary<String, Double> result = json.ToDictionary (x => x.NinjaName, y => y.NinjaPrice);
}

与上面的结果相同,但现在解析是通过ParenObj具有自定义 getter 的类完成的。

于 2013-06-18T13:25:44.113 回答