2017-02-28 28 views
4

我試圖解析一個文本文件,但我覺得必須有一個更好的方法來做到這一點。有沒有簡單的方法來解析C#中的結構化文本文件?

文本文件由項目組成,其中可以包含鍵值對以及其他項目。我相信該文件將只會像孫子項目一樣深(例如項目內的項目,項目內)。

目前我通過逐行遍歷文件,並跟蹤我的深度。然後,一旦我達到終止字符('}'),我在0級,我知道我已經捕獲了一個完整的父項。

由於我不認爲我解釋得很好,所以我的文件結構看起來與此類似。

parent_item { 
key: value 
key: value 
child_item { 
    key: value 
    key: value 
} 
child_item { 
    key: value 
    key: value 
    key: value 
    grandchild_item { 
     key: value 
     key: value 
    } 
} 
key: value 
key: value 
} 
parent_item { 
    key: value 
    key: value 
    child_item { 
     key: value 
     key: value 
    } 
} 

每個項目可以有0到許多子項,但我不認爲它永遠不會去深度超過3個級別(父 - >子 - >孫)。

有沒有更簡單的方法來解析這個問題,還是我正朝着正確的方向工作?

+0

「我試圖解析一個文本文件,但我覺得必須有更好的方法來完成它。」 - 是的,很多人已經做到了。不要重新發明輪子,尋找現有的解析器並將其用於項目中。 –

+0

@ rory.ap也許我在用錯誤的術語搜索,但我很難找到符合我需求的現有解析器。有什麼建議麼?或搜索條件的建議? – Tester101

+3

看起來像[JSON](https://en.wikipedia.org/wiki/JSON) –

回答

-1

使用序列化。

在C#中,您可以輕鬆使用JSON或XML序列化。

JSON: https://msdn.microsoft.com/en-us/library/bb412179(v=vs.110).aspx

一個更好的方式是XML,因爲它更靈活,在C#中的更好的支持: https://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx

+0

這是如何回答這個問題的?他被要求使用現有的工具來閱讀一個非常具體的格式。 – InBetween

+0

這不是JSON,所以JSON序列化不起作用 – bradbury9

+0

好吧,它不是JSON,但它是相似的!如果你編寫2行代碼將其轉換爲JSON(用「:」和\ n替換爲「,」),你就有一個JSON格式的字符串 – Adriano

3

你的文件看起來幾乎像JSON,除了有之間沒有冒號複雜嵌套對象的屬性名稱。但是,您將無法使用JSON.NET之類的JSON解析器,這一點已經不同了。

我建議像你一樣手動解析它 - 但使用堆棧和狀態機。每當您遇到開放捲曲時,您的狀態機應推入堆棧{,並在您收到關閉卷曲}時從堆棧彈出。

1

與JSON非常相似,如果格式是固定的(打開卷曲'{'並且結束捲曲}作爲行中的最後一個字符),您可以將該文本轉換爲JSON並稍作更改。 警告,沒有測試過,像這樣

StringBuilder jsonEncoded = new StringBuilder(); 
string[] lines = content.Split("\n"); 
foreach(string line in lines) 
{ 
    if(line.EndsWith("{") || line.EndsWith("}") 
     jsonEncoded.AppendLine(line); 
    else 
     jsonEncoded.AppendLine(line + ","); 
} 

之後,定期JSON Deseralization會工作。

1

如果您可以信任您的源代碼而不是搞亂這個模式,那麼您可以編寫一個解決方法。我對你有一些想法:

JSON

它看起來像json。也許你可以規範化它,然後用JSON.NET解析它。

我只寫了一個醜陋的工作解決方案。試試吧here

using System; 
using System.Text.RegularExpressions; 

public class Program 
{ 
    public static string Quoterize(string s) 
    { 
     return Regex.Replace(s, @"\w+", match => "\"" + match + "\""); 
    } 

    public static string RewriteThisPlease(string s) 
    { 
     return s 
      .Replace("\n", "," + Environment.NewLine) 
      .Replace(" ", "") 
      .Replace(Environment.NewLine, "") 
      .Replace("{,", "{") 
      .Replace(",}", "}"); 
    } 

    public static void Main() 
    { 
     var k = @""; // your file goes here 
     Console.WriteLine("{"+MoveToRegexPlease(Quoterize((k).Replace("{", ": {")))+"}"); 
    } 
} 

YAML

它看起來像JSON。它看起來更像yaml。一個YAML驗證器會接受你的文件經過兩次simples取代:

// where k is your file as string 
Console.WriteLine(k.Replace("{\n", ":\n").Replace("}","")); 

Demo

自制

它看起來像JSON。你會在那裏找到很多JSON解析器,也許你可以找到一個解析器並使其適應你的案例。

作業

看起來像json。你會在那裏找到很多JSON解析器教程。編寫一個小解析器總是一個很好的練習。

祝你好運!

+0

相當不錯,但在YAML的情況下,我會建議有點限制'替換(「{\ n」,「:\ n」)'以避免與字符串屬性/值混淆。 – bradbury9

+0

@ bradbury9不錯的想法 – aloisdg

0

下面是一個簡單的例子與Balancing Group Definitions

此示例使用代碼從鏈路(雖然沒有仔細尚未測試)使用RegEx的。我只是取代了括號不改變代碼,並使用它,因爲它是:

static void Main(string[] args) 
{ 
    // here I read your posted file 
    string input = System.IO.File.ReadAllText("test.txt"); 

    input = input.Replace('{', '<'); 
    input = input.Replace('}', '>'); 

    string pattern = "^[^<>]*" + 
       "(" + 
       "((?'Open'<)[^<>]*)+" + 
       "((?'Close-Open'>)[^<>]*)+" + 
       ")*" + 
       "(?(Open)(?!))$"; 

    //string input = "<abc><mno<xyz>>"; 

    Match m = Regex.Match(input, pattern); 
    if (m.Success == true) 
    { 
     Console.WriteLine("Input: \"{0}\" \nMatch: \"{1}\"", input, m); 
     int grpCtr = 0; 
     foreach (Group grp in m.Groups) 
     { 
      Console.WriteLine(" Group {0}: {1}", grpCtr, grp.Value); 
      grpCtr++; 
      int capCtr = 0; 
      foreach (Capture cap in grp.Captures) 
      { 
       Console.WriteLine("  Capture {0}: {1}", capCtr, cap.Value); 
       capCtr++; 
      } 
     } 
    } 
    else 
    { 
     Console.WriteLine("Match failed."); 
    } 

    Console.ReadKey(); 
} 

複製粘貼到一個新的控制檯項目,讓它運行和看一看的輸出。它一開始就讓人感到困惑,但它可能會給你一個啓動器以適應你的需求。

+0

您不應該使用縮寫來命名變量 – aloisdg

+0

@aloisdg完全正確。正如你可以在我的帖子中看到的,這段代碼來自msdn站點。我沒有故意改變它。 –

相關問題