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)\",\"忍者\":\"レオナルド - $0.99\",\"データ\":[[1336485655241,0.99],[1336566333236,0.99 ],[1336679536073,0.99],[1336706394834,0.99],[1336774593068,0.99],[1366284992043,0.99]]},{\"バンダナカラー\":\"rgb(128,0,128)\",\"忍者\ ":\"ドナテロ - $0.25\",\"データ\":[[1361061084420,0.23],[1366102471587,0.25],[1366226367262,0.25],[1366284992043,0.25]]},{\"bandanaColor\": \"rgb(255,0,0)\",\"忍者\":\"ラファエル - $0.15\",\"データ\":[[1327305600000,0.15],[1365583220422,0.15],[1365669396241,0.15 ],[1365669396241,0.15],[1365753433493,0.15],[1366284992043,0.15]]},{\"bandanaColor\":\"rgb(255,165,0)\",\"忍者\":\"ミケランジェロ - $0.14\",\"データ\":[1366284992043,0.14]}]

(これは、このようなサイトを使用してテストできます。)

さて、解析に関する限り、正規表現は問題になるでしょう。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 

単純な文字列解析 ( のインスタンスによる分割-) を使用しましたが、必要に応じてさらに複雑にすることもできます。


2 番目のバージョン

(オブジェクトを作成していないため) 投資時間は少し長くなりますが、その見返りは、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);
}

上記と同じ結果ですが、ParenObjカスタムゲッターを使用してクラスを介して解析が行われます。

于 2013-06-18T13:25:44.113 に答える