【问题标题】:Need help modifying a regex that once worked需要帮助修改曾经有效的正则表达式
【发布时间】:2013-06-14 16:54:03
【问题描述】:

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

代码如下:

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.

【问题讨论】:

  • Newtsonsoft 的 Json.NET 会让这变得更容易(无需尝试使用正则表达式破解它)。
  • 我不是第一次听说 Json.Net!但我不知道它是如何工作的。我去看看,但这并不能解决我现在的问题
  • 使用正则表达式并不能解决您的问题。如果你要解析 JSON 数据,你不能不使用为吃、睡和呼吸 JSON 对象而编写的解析器。
  • 哦,好的。因此,如果我理解得很好,我正在阅读的是一个 JSon 对象,并且由于我将它收集在一个字符串中并尝试在其上使用正则表达式,我只会让它变得更难?
  • 另外,你有 JSON 错误(最后一个 data: 应该是 data: [[...]](它是一个双数组,但只从一个开头开始 [--可能是复制粘贴错误?)

标签: c# regex string dictionary


【解决方案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.25\",\"数据\":[[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\":\ "米开朗基罗 - $0.14\",\"数据\":[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 语法。相反,它将数据序列化为类(您已创建)使检索信息更加流畅。例如

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);
}

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

【讨论】:

  • 有趣。我撞车了。难道是我需要在反序列化对象之前删除“var results =”行吗?
  • 这只是在:我发现html视图中使用的其余javascript也在字符串中找到。所以我有这个错误弹出:Additional text encountered after finished reading JSON content: ;. Path '', line 54, position 2.
  • @HerveS:在将字符串传递给JsonConvert.DeserializeObject之前,先调用字符串上的.TrimEnd(';')
  • 快到了!我设法用你给我的东西得到了字典,但是得到的字典有问题。每个双精度数都是 0。但是数组中的双精度数是好的。 IDictionary 行有问题吗?
  • @HerveS:您能否提供一个您尝试解析的 JSOn 示例?还有,你用的是哪个版本,第一个还是第二个?
猜你喜欢
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-30
  • 2023-03-19
  • 1970-01-01
相关资源
最近更新 更多