按固定宽度将字符串拆分为子字符串

时间:2012-07-06 15:44:17

标签: c# winforms

我的数据看起来像这样......

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

我的问题是,将这些数据拆分成较小的子串的最有效方法是什么,因为会有数百行。此外,一些行将缺少最后一列。我试图做正则表达式,但是我用于宽度的模式没有成功。上面的数据应该分解为这些字段(下面列出的每列的长度)

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

任何人都可以伸出援手或建议一个好的正则表达式匹配模式来提取信息吗?

谢谢, 西蒙

3 个答案:

答案 0 :(得分:7)

尝试以下正则表达式:

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

如果值总是非空的并且用空格分隔(也就是说,它们不会相互碰撞),那么尝试更简单的事情,如

line.Split(" ")

答案 1 :(得分: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将允许您直接将数据读取为固定宽度数据。

答案 2 :(得分:6)

在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();
}