2016-07-09 3 views
0

私はLuaを使って保存されたテーブルだけを含んでいるファイルを解析したいと思いますが、情報は論理的(理解しやすい)ですが、ストレージのコンセプトは従来のLua解析手法を使用するのが非常に困難です。C#を使用して奇妙な構造を持つLuaテーブルを解析するには?

例えば

が、これは構造体の一部からスニップです:

["Bag-3"] = { 
    ["ids"] = { 
     2589, -- [1] 
     108996, -- [2] 
     4306, -- [3] 
     2453, -- [4] 
     108330, -- [5] 
     2450, -- [6] 
     4337, -- [7] 
     2592, -- [8] 
     108326, -- [9] 
     6470, -- [10] 
     1529, -- [11] 
     4338, -- [12] 
     3404, -- [13] 
     3685, -- [14] 
     108325, -- [15] 
     108324, -- [16] 
     7067, -- [17] 
     785, -- [18] 
     5503, -- [19] 
     5504, -- [20] 
     7069, -- [21] 
     5500, -- [22] 
     108323, -- [23] 
     12662, -- [24] 
     53010, -- [25] 
     62791, -- [26] 
     76061, -- [27] 
     74866, -- [28] 
     120945, -- [29] 
     109131, -- [30] 
     111557, -- [31] 
     30817, -- [32] 
     89112, -- [33] 
     30183, -- [34] 
     23572, -- [35] 
     36931, -- [36] 
     34057, -- [37] 
     43102, -- [38] 
     74249, -- [39] 
     72120, -- [40] 
     79010, -- [41] 
     72092, -- [42] 
     72094, -- [43] 
     72103, -- [44] 
     102542, -- [45] 
     102543, -- [46] 
     102541, -- [47] 
     72163, -- [48] 
     36925, -- [49] 
     36919, -- [50] 
     36928, -- [51] 
     36934, -- [52] 
     21877, -- [53] 
     12205, -- [54] 
     10285, -- [55] 
     3356, -- [56] 
     [97] = 72988, 
     [95] = 82441, 
     [96] = 72988, 
     [98] = 72988, 
    }, 
    ["links"] = { 
     "|cffffffff|Hitem:2589:0:0:0:0:0:0:0:100:264:0:0:0|h[Linen Cloth]|h|r", -- [1] 
     "|cff1eff00|Hitem:108996:0:0:0:0:0:0:0:100:264:0:0:0|h[Alchemical Catalyst]|h|r", -- [2] 
     "|cffffffff|Hitem:4306:0:0:0:0:0:0:0:100:264:0:0:0|h[Silk Cloth]|h|r", -- [3] 
     "|cffffffff|Hitem:2453:0:0:0:0:0:0:0:100:264:0:0:0|h[Bruiseweed]|h|r", -- [4] 
     "|cffffffff|Hitem:108330:0:0:0:0:0:0:0:100:264:0:0:0|h[Stranglekelp Blade]|h|r", -- [5] 
     "|cffffffff|Hitem:2450:0:0:0:0:0:0:0:100:264:0:0:0|h[Briarthorn]|h|r", -- [6] 
     "|cffffffff|Hitem:4337:0:0:0:0:0:0:0:100:264:0:0:0|h[Thick Spider's Silk]|h|r", -- [7] 
     "|cffffffff|Hitem:2592:0:0:0:0:0:0:0:100:264:0:0:0|h[Wool Cloth]|h|r", -- [8] 
     "|cffffffff|Hitem:108326:0:0:0:0:0:0:0:100:264:0:0:0|h[Khadgar's Whisker Stem]|h|r", -- [9] 
     "|cffffffff|Hitem:6470:0:0:0:0:0:0:0:100:264:0:0:0|h[Deviate Scale]|h|r", -- [10] 
     "|cff1eff00|Hitem:1529:0:0:0:0:0:0:0:100:264:0:0:0|h[Jade]|h|r", -- [11] 
     "|cffffffff|Hitem:4338:0:0:0:0:0:0:0:100:264:0:0:0|h[Mageweave Cloth]|h|r", -- [12] 
     "|cffffffff|Hitem:3404:0:0:0:0:0:0:0:100:264:0:0:0|h[Buzzard Wing]|h|r", -- [13] 
     "|cffffffff|Hitem:3685:0:0:0:0:0:0:0:100:264:0:0:0|h[Raptor Egg]|h|r", -- [14] 
     "|cffffffff|Hitem:108325:0:0:0:0:0:0:0:100:264:0:0:0|h[Liferoot Stem]|h|r", -- [15] 
     "|cffffffff|Hitem:108324:0:0:0:0:0:0:0:100:264:0:0:0|h[Kingsblood Petal]|h|r", -- [16] 
     "|cffffffff|Hitem:7067:0:0:0:0:0:0:0:100:264:0:0:0|h[Elemental Earth]|h|r", -- [17] 
     "|cffffffff|Hitem:785:0:0:0:0:0:0:0:100:264:0:0:0|h[Mageroyal]|h|r", -- [18] 
     "|cffffffff|Hitem:5503:0:0:0:0:0:0:0:100:264:0:0:0|h[Clam Meat]|h|r", -- [19] 
     "|cffffffff|Hitem:5504:0:0:0:0:0:0:0:100:264:0:0:0|h[Tangy Clam Meat]|h|r", -- [20] 
     "|cffffffff|Hitem:7069:0:0:0:0:0:0:0:100:264:0:0:0|h[Elemental Air]|h|r", -- [21] 
     "|cff1eff00|Hitem:5500:0:0:0:0:0:0:0:100:264:0:0:0|h[Iridescent Pearl]|h|r", -- [22] 
     "|cffffffff|Hitem:108323:0:0:0:0:0:0:0:100:264:0:0:0|h[Wild Steelbloom Petal]|h|r", -- [23] 
     "|cff1eff00|Hitem:12662:0:0:0:0:0:0:0:100:264:0:0:0|h[Demonic Rune]|h|r", -- [24] 
     "|cffffffff|Hitem:53010:0:0:0:0:0:0:0:100:264:0:0:0|h[Embersilk Cloth]|h|r", -- [25] 
     "|cffffffff|Hitem:62791:0:0:0:0:0:0:0:100:264:0:0:0|h[Blood Shrimp]|h|r", -- [26] 
     "|cff0070dd|Hitem:76061:0:0:0:0:0:0:0:100:264:0:0:0|h[Spirit of Harmony]|h|r", -- [27] 
     "|cffffffff|Hitem:74866:0:0:0:0:0:0:0:100:264:0:0:0|h[Golden Carp]|h|r", -- [28] 
     "|cff1eff00|Hitem:120945:0:0:0:0:0:0:0:100:264:0:0:0|h[Primal Spirit]|h|r", -- [29] 
     "|cffffffff|Hitem:109131:0:0:0:0:0:0:0:100:264:0:0:0|h[Raw Clefthoof Meat]|h|r", -- [30] 
     "|cffffffff|Hitem:111557:0:0:0:0:0:0:0:100:264:0:0:0|h[Sumptuous Fur]|h|r", -- [31] 
     "|cffffffff|Hitem:30817:0:0:0:0:0:0:0:100:264:0:0:0|h[Simple Flour]|h|r", -- [32] 
     "|cffffffff|Hitem:89112:0:0:0:0:0:0:0:100:264:0:0:0|h[Mote of Harmony]|h|r", -- [33] 
     "|cffa335ee|Hitem:30183:0:0:0:0:0:0:0:100:264:0:0:0|h[Nether Vortex]|h|r", -- [34] 
     "|cff0070dd|Hitem:23572:0:0:0:0:0:0:0:100:264:0:0:0|h[Primal Nether]|h|r", -- [35] 
     "|cffa335ee|Hitem:36931:0:0:0:0:0:0:0:100:264:0:0:0|h[Ametrine]|h|r", -- [36] 
     "|cffa335ee|Hitem:34057:0:0:0:0:0:0:0:100:264:0:0:0|h[Abyss Crystal]|h|r", -- [37] 
     "|cff0070dd|Hitem:43102:0:0:0:0:0:0:0:100:264:0:0:0|h[Frozen Orb]|h|r", -- [38] 
     "|cffffffff|Hitem:74249:0:0:0:0:0:0:0:100:264:0:0:0|h[Spirit Dust]|h|r", -- [39] 
     "|cffffffff|Hitem:72120:0:0:0:0:0:0:0:100:264:0:0:0|h[Exotic Leather]|h|r", -- [40] 
     "|cffffffff|Hitem:79010:0:0:0:0:0:0:0:100:264:0:0:0|h[Snow Lily]|h|r", -- [41] 
     "|cffffffff|Hitem:72092:0:0:0:0:0:0:0:100:264:0:0:0|h[Ghost Iron Ore]|h|r", -- [42] 
     "|cff1eff00|Hitem:72094:0:0:0:0:0:0:0:100:264:0:0:0|h[Black Trillium Ore]|h|r", -- [43] 
     "|cff1eff00|Hitem:72103:0:0:0:0:0:0:0:100:264:0:0:0|h[White Trillium Ore]|h|r", -- [44] 
     "|cff1eff00|Hitem:102542:0:0:0:0:0:0:0:100:264:0:0:0|h[Ancient Pandaren Spices]|h|r", -- [45] 
     "|cff1eff00|Hitem:102543:0:0:0:0:0:0:0:100:264:0:0:0|h[Aged Mogu'shan Cheese]|h|r", -- [46] 
     "|cff1eff00|Hitem:102541:0:0:0:0:0:0:0:100:264:0:0:0|h[Aged Balsamic Vinegar]|h|r", -- [47] 
     "|cff0070dd|Hitem:72163:0:0:0:0:0:0:0:100:264:0:0:0|h[Magnificent Hide]|h|r", -- [48] 
     "|cffa335ee|Hitem:36925:0:0:0:0:0:0:0:100:264:0:0:0|h[Majestic Zircon]|h|r", -- [49] 
     "|cffa335ee|Hitem:36919:0:0:0:0:0:0:0:100:264:0:0:0|h[Cardinal Ruby]|h|r", -- [50] 
     "|cffa335ee|Hitem:36928:0:0:0:0:0:0:0:100:264:0:0:0|h[Dreadstone]|h|r", -- [51] 
     "|cffa335ee|Hitem:36934:0:0:0:0:0:0:0:100:264:0:0:0|h[Eye of Zul]|h|r", -- [52] 
     "|cffffffff|Hitem:21877:0:0:0:0:0:0:0:100:264:0:0:0|h[Netherweave Cloth]|h|r", -- [53] 
     "|cffffffff|Hitem:12205:0:0:0:0:0:0:0:100:264:0:0:0|h[White Spider Meat]|h|r", -- [54] 
     "|cffffffff|Hitem:10285:0:0:0:0:0:0:0:100:264:0:0:0|h[Shadow Silk]|h|r", -- [55] 
     "|cffffffff|Hitem:3356:0:0:0:0:0:0:0:100:264:0:0:0|h[Kingsblood]|h|r", -- [56] 
     [97] = "|cffffffff|Hitem:72988:0:0:0:0:0:0:0:100:264:0:0:0|h[Windwool Cloth]|h|r", 
     [95] = "|cffffffff|Hitem:82441:0:0:0:0:0:0:0:100:264:0:0:0|h[Bolt of Windwool Cloth]|h|r", 
     [96] = "|cffffffff|Hitem:72988:0:0:0:0:0:0:0:100:264:0:0:0|h[Windwool Cloth]|h|r", 
     [98] = "|cffffffff|Hitem:72988:0:0:0:0:0:0:0:100:264:0:0:0|h[Windwool Cloth]|h|r", 
    }, 
    ["counts"] = { 
     51, -- [1] 
     5, -- [2] 
     76, -- [3] 
     9, -- [4] 
     10, -- [5] 
     8, -- [6] 
     2, -- [7] 
     28, -- [8] 
     41, -- [9] 
     nil, -- [10] 
     nil, -- [11] 
     nil, -- [12] 
     5, -- [13] 
     5, -- [14] 
     28, -- [15] 
     76, -- [16] 
     nil, -- [17] 
     3, -- [18] 
     10, -- [19] 
     8, -- [20] 
     2, -- [21] 
     nil, -- [22] 
     53, -- [23] 
     nil, -- [24] 
     8, -- [25] 
     5, -- [26] 
     nil, -- [27] 
     10, -- [28] 
     16, -- [29] 
     nil, -- [30] 
     nil, -- [31] 
     20, -- [32] 
     128, -- [33] 
     9, -- [34] 
     nil, -- [35] 
     2, -- [36] 
     nil, -- [37] 
     nil, -- [38] 
     40, -- [39] 
     148, -- [40] 
     20, -- [41] 
     46, -- [42] 
     45, -- [43] 
     23, -- [44] 
     18, -- [45] 
     5, -- [46] 
     8, -- [47] 
     2, -- [48] 
     nil, -- [49] 
     nil, -- [50] 
     2, -- [51] 
     nil, -- [52] 
     30, -- [53] 
     14, -- [54] 
     nil, -- [55] 
     3, -- [56] 
     [97] = 200, 
     [95] = 2, 
     [98] = 200, 
    }, 
    ["size"] = 98, 
}, 

あなたが気付いた場合、特にカウントの下に、下の3が、すべては(その特定の袋のスロット内の項目の数ですこれはWarcraftのdatastore_containersアドオンから保存されたデータです)。しかし、リスト内の最後の三つ(これは異なる)、この形式である:

[bag slot #] = count 

どのようにインデックスから最後の三つを除い例えばスロット番号(、(両方としてこのツリー妥当通過できます

理想的には、私はプロジェクトにソースコードを直接埋め込むことができますが、別の前処理を追加するのではなく、

答えて

1

これは実際にはテーブルを適切に解析するだけの問題です。混乱が生じるかもしれません。理由だけで、テーブルがレイアウトされている方法で、分解が読むことを少し簡単にする必要があります:

["Bag-3"] = { 
    ["ids"] = { 
     2589, -- [1] 
     ... 
     3356, -- [56] 
     [97] = 72988, 
     [95] = 82441, 
    }, 
    ["links"] = { 
     "|cffffffff|Hitem:2589:0:0:0:0:0:0:0:100:264:0:0:0|h[Linen Cloth]|h|r", -- [1] 
     ... 
     "|cffffffff|Hitem:3356:0:0:0:0:0:0:0:100:264:0:0:0|h[Kingsblood]|h|r", -- [56] 
     [97] = "|cffffffff|Hitem:72988:0:0:0:0:0:0:0:100:264:0:0:0|h[Windwool Cloth]|h|r", 
     [95] = "|cffffffff|Hitem:82441:0:0:0:0:0:0:0:100:264:0:0:0|h[Bolt of Windwool Cloth]|h|r", 
    }, 
    ["counts"] = { 
     51, -- [1] 
     ... 
     3, -- [56] 
     [97] = 200, 
     [95] = 2, 
    }, 
    ["size"] = 98, 
}, 

まず、Luaの中のコメントは--によってマークされているので、-- [X]で終わる行は単なるコメントです[X]が配列内の特定のインデックス(n+1)であり、,より前の値が配列内のそのインデックスの値であることを示します。

インデックスに関連付けられた値がない場合、値はデフォルトでnull(またはLuaではnil)になります。コメントがなく、明示的にインデックスを指定している行(例:[97] = 72988,)は明示的なセッターです。

テーブルは一致する値がそのインデックスをコメントとして持つように(インデックスを明示的に指定する必要はない)、テーブルの一致値が56(この例では)で終了するため、明示的に割り当てられているので、3356, -- [56]の後に[97] = 72988,のようなものが表示されます。 [97]の値は明示的に設定する必要があります。なぜなら、それと[56]の間に何もないからです。なぜなら、いくつかの値が順不同で表示されるからです。

"バッグ"が同じ正確なレイアウト(必ずしも同じ値ではなく、同じ "テーブル"レイアウト)を持つ場合、クラスを使用してこれを解析することができます(外部ライブラリは不要です)。 ["size"]プロパティは、利用例です。そして、

class Bag 
{ 
    public string Name = string.Empty; 
    public int Size = 0; 

    public List<int?> Counts = new List<int?>(); 
    public List<int?> IDs = new List<int?>(); 
    public List<string> Links = new List<string>(); 

    public Bag() { } 

    public static Bag Parse(string input) 
    { 
     Bag bag = new Bag(); 
     int? iv = null; 
     int idx = input.IndexOf("[\"") + 2; 
     bag.Name = input.Substring(idx, input.IndexOf("\"]") - idx); 
     idx = input.IndexOf("[\"size\"] = ") + "[\"size\"] = ".Length; // len; 
     bag.Size = int.Parse(input.Substring(idx, input.Substring(idx).IndexOf(","))); 

     foreach (object val in GetVals("ids", input, bag.Size)) { 
      iv = null; 
      if (val != null && val.ToString() != "nil") { 
       iv = int.Parse(val.ToString()); 
      } 
      bag.IDs.Add(iv); 
     } 

     foreach (object val in GetVals("links", input, bag.Size)) { 
      bag.Links.Add((string)val); 
     } 

     foreach (object val in GetVals("counts", input, bag.Size)) { 
      iv = null; 
      if (val != null && val.ToString() != "nil") { 
       iv = int.Parse(val.ToString()); 
      } 
      bag.Counts.Add(iv); 
     } 
     return bag; 
    } 

    private static List<object> GetVals(string id, string input, int size) 
    { 
     List<object> list = new List<object>(); 
     for (int i = 0; i < size; ++i) { list.Add(null); } 
     string tmp, ival = string.Format("[\"{0}\"] = {{", id); 
     string[] tsplit = null; 
     int len = ival.Length; 
     int idx = input.IndexOf(ival) + len; 
     foreach (string val in input.Substring(idx, input.Substring(idx).IndexOf("}")).Split('\n')) { 
      tmp = val.Trim(); 
      if (string.IsNullOrEmpty(tmp)) { continue; } 
      tsplit = tmp.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); 
      if (tsplit.Length == 2) { 
       int i = (int.Parse((((tsplit[1].Replace("-", "")).Replace("[", "")).Replace("]", "")).Trim()) - 1); 
       list[i] = tsplit[0].Trim(); 
      } else { 
       int i = (int.Parse((tsplit[0].Substring(0, tsplit[0].IndexOf("=")).Replace("[", "")).Replace("]", "").Trim()) - 1); 
       list[i] = tsplit[0].Substring(tsplit[0].IndexOf("=") + 1).Trim(); 
      } 
     } 
     return list; 
    } 
} 

使用する:Bag b = Bag.Parse(bagTableValue);

は、これは、より単純化した例であり、あなたは(RegExのような)他の方法を使用することができますが、それは、テーブルを解析する方法を説明するために多くのです。助けることができる

希望。

関連する問題