2016-04-27 78 views
0

我試圖使用dotnet c#解析和拆分下面的示例文本文件,以便將每個單獨的數據點分解爲單獨的字符串。C#將文本合格文件解析爲單獨的字符串

§Id§|§Name§|§UpdateDate§|§Description§ 
1|§AAA/FE-45§|2000-02-02 00:00:00|§§ 
2|§BBB-123§|2000-02-03 00:00:00|§§ 
3|§CC|45§|2000-02-07 00:00:00|§The following, 
is a multiline description 
please check Name: 
CC|45 as soon as possible§ 

文件屬性:

CodePage: ANSI 
Column Headers: Yes 
Row Delimiter: {CR}{LF} 
Column Delimiter: | (Vertical Bar) 
Text Qualifier: § 

麻煩我是文本類型的列有資格用非標準符號與給定文本可以是一個塊多行文本可能包含各種符號,如{CRLF},{LF}或甚至| (垂直條)。

從我可以讀到的周圍,我不能使用TextFieldParser,因爲它只處理雙引號限定符和大容量插入不支持文本限定符。 我不是c#專家;我不想重新發明輪子,理想情況下希望使用最佳做法。但我也喜歡理解和「擁有」我所生產的產品,所以我寧願避免使用像Filehelpers這樣的庫。 感謝您的指導!

+1

你檢查['String.Split()'](https://msdn.microsoft.com/en-us/library/b873y76a(V = vs.110).aspx)方法? – Sidewinder94

+0

問題是,豎線不僅可以是列分隔符,也可以是列值的一部分。 – Gabor

+0

爲什麼不把時髦的文本分隔符更改爲「然後標記」,這仍然會留下有效的數據 – BugFinder

回答

0

試試這個代碼

string pattern = @"(?<id>\d+) \| (?<name>§.+?§) \| (?<date>\d{4}-\d\d-\d\d \s \d\d:\d\d:\d\d) \| (?<desc>§.*?§)"; 
Regex regex = new Regex(pattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline); 

string text = File.ReadAllText("test.txt", Encoding.GetEncoding(1251)); 
text = text.Split(new string[] { Environment.NewLine }, 2, StringSplitOptions.None)[1]; 

var matches = regex.Matches(text); 

foreach (Match match in matches) 
{ 
    Console.WriteLine(match.Groups["id"].Value); 
    Console.WriteLine(match.Groups["name"].Value.Trim('§')); 
    Console.WriteLine(match.Groups["date"].Value); 
    Console.WriteLine(match.Groups["desc"].Value.Trim('§')); 
    Console.WriteLine(); 
} 
1

的典型方法是使用有限自動機這一點。你的情況,你可以試試下面的代碼:

public static List<string[]> split(string s) 
    { 
     bool ins = false; 
     int no = 3; 
     var L = new List<string>(); 
     var Res = new List<string[]>(); 
     var B = new StringBuilder(); 
     foreach (var c in s) 
     { 
      switch (c) 
      { 
       case '§': 
        if (ins) 
        { 
         ins = false; 
         L.Add(B.ToString()); 
         if (no == 0) 
         { 
          Res.Add(L.ToArray<string>()); 
          L.Clear(); 
          no = 3; 
         } 
        } 
        else 
        { 
         ins = true; 
         B.Clear(); 
        } 
        break; 
       case '|': 
        if (!ins) { no--; } 
        else B.Append(c); 
        break; 
       default: 
        if (ins) B.Append(c); 
        break; 
      } 
     } 
     return Res; 
    } 
} 
相關問題