需要帮助修改曾经工作的正则表达式

时间:2013-06-18 12:58:23

标签: c# regex string dictionary

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

以下是代码:

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”。所以我最终会得到这些价值观:

Key \ Value

莱昂纳多\ 0.99

Donatello \ 0.25

Raphael \ 0.15

米开朗基罗\ 0.14

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

任何人都可以帮助我找出如何获得我想要的东西吗?

修改

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

An item with the same key has already been added.

1 个答案:

答案 0 :(得分:1)

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

  

[{\&#34; bandanaColor \&#34;:\&#34; RGB(0,0,255)\&#34; \&#34;忍者\&#34;:\&#34 ;莱昂纳多 - $ 0.99 \&#34;,&#34;数据\&#34;:[[1336485655241,0.99],[1336566333236,0.99],[1336679536073,0.99],[1336706394834,0.99],[1336774593068, 0.99],[1366284992043,0.99]]},{\&#34; bandanaColor \&#34;:\&#34; RGB(128,0,128)\&#34; \&#34;忍者\&# 34;:\&#34; Donatello - $ 0.25 \&#34;,&#34; data \&#34;:[[1361061084420,0.23],[1366102471587,0.25],[1366226367262,0.25],[1366284992043 ,0.25]]},{\&#34; bandanaColor \&#34;:\&#34; RGB(255,0,0)\&#34; \&#34;忍者\&#34 ;:拉斐尔 - $ 0.15 \&#34;,&#34;数据\&#34;:[[1327305600000,0.15],[1365583220422,0.15],[1365669396241,0.15],[1365669396241,0.15] [1365753433493,0.15],[1366284992043,0.15]]},{\&#34; bandanaColor \&#34;:\&#34; RGB(255,165,0)\&#34; \&#34;忍者\&#34;:\&#34;米开朗基罗 - $ 0.14 \&#34;,&#34;数据\&#34;:[1366284992043,0.14]}]

(可以使用像this one这样的网站进行测试。)

现在,就解析而言,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语法。相反,它会序列化类中的数据(您已经创建)使得检索信息更加流畅。 e.g。

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完成的。