9

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

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

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

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

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

谢谢,西蒙

4

3 回答 3

8

尝试以下正则表达式:

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

如果这些值始终为非空并用空格分隔(也就是说,它们不会相互碰撞),那么尝试一些更简单的方法,例如

line.Split(" ")
于 2012-07-06T15:54:07.603 回答
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将允许您直接将数据作为固定宽度数据读取。

于 2012-07-06T15:46:37.897 回答
6

查看 MSDN 上的此链接:

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

基本上,这个TextFieldParser类正是做这种事情。这也是读取分隔数据(如 CSV 文件)的好方法。无论出于何种原因,Microsoft 选择将它放在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();
}
于 2012-07-06T15:54:01.573 回答