2012-07-06 86 views
7

我有看起來像這樣的數據...將一個字符串分解成子串由固定寬度

1 TESTAAA  SERNUM A DESCRIPTION 
    2 TESTBBB  ANOTHR ANOTHER DESCRIPTION 
    3 TESTXXX  BLAHBL 

我的問題是,什麼是分裂這個數據到它的體積更小的子串的最有效方法,因爲會有數百條線路。另外,一些行將會丟失最後一列。我試圖做正則表達式,但用寬度的模式不成功。上面的數據應分解成這些字段(各列的長度在下面列出)

{id} {firsttext} {serialhere} {description} 
4 22   6   30+ 

誰能幫忙或提供一個良好的正則表達式匹配的圖案以提取信息?

感謝, 西蒙

回答

7

試試下面的正則表達式:

(.{4})(.{22})(.{6})(.+)? 

如果值總是非空,並用空格分隔(即,他們不」牛逼碰到對方),然後嘗試一些簡單的像

line.Split(" ") 
6

我真的建議通過書面形式直接String.Substring做到這一點的方法。這可能會更有效地給你確切的所需寬度。

這可能會工作(雖然它是未經測試,並有意不會刪除字符串填充):

public static string[] SplitFixedWidth(string original, bool spaceBetweenItems, params int[] widths) 
{ 
    string[] results = new string[widths.Length]; 
    int current = 0; 

    for (int i = 0; i < widths.Length; ++i) 
    { 
     if (current < original.Length) 
     { 
      int len = Math.Min(original.Length - current, widths[i]); 
      results[i] = original.Substring(current, len); 
      current += widths[i] + (spaceBetweenItems ? 1 : 0); 
     } 
     else results[i] = string.Empty; 
    } 

    return results; 
} 

話雖這麼說,如果你從一個Stream或文本文件直接讀這篇文章,使用TextFieldParser將允許您直接以固定寬度數據讀取數據。

+0

TextFieldParse可以從任何流或TextReader的,s的讀取o它不必去物理文件。 – 2012-07-06 15:58:36

+0

@SteveDog是的 - 數據確實需要在流中。但這並不是一個問題,但如果你已經(出於某種原因)有一個正在處理的字符串數組,或者類似的東西,我不一定會把它放在那裏。這就是說,我編輯了包含該信息 – 2012-07-06 16:01:34

+0

不,我說它也需要一個TextReader,所以你可以像new TextFieldParser(new StringReader(「data」))''那樣實例化它。沒有必要的流。 – 2012-07-06 16:03:26

5

退房的MSDN此鏈接:

http://msdn.microsoft.com/en-us/library/zezabash.aspx

基本上,TextFieldParser類不正是這種事情。這也是讀取分隔數據(如CSV文件)的好方法。無論出於何種原因,微軟選擇將其置於Microsoft.VisualBasic.FileIO命名空間下,這很煩人,因爲它實際上與VB沒有任何關係。

例如,你可以使用它像這樣:

TextFieldParser parser = new TextFieldParser(new StringReader(fixedWidthData)); 
parser.TextFieldType = FieldType.FixedWidth; 
parser.SetFieldWidths(4, 22, 6, -1); 
while (!parser.EndOfData) 
{ 
    string[] row = parser.ReadFields(); 
} 
相關問題