【问题标题】:How do I parse a random space-separated text file and turn into tab-separated file如何解析随机空格分隔的文本文件并转换为制表符分隔的文件
【发布时间】:2015-06-27 23:58:40
【问题描述】:

我正在阅读一个巨大的、机器生成的、制表符分隔的文本文件。我在下面制作了以下代码来获取值,但这仅在文本文件以制表符分隔的方式时才有效,并且事实证明 外部软件 在每个之间使用随机数量的空格字段。

如何生成将随机空格分隔的文本文件读入制表符分隔文件的代码。我目前的解决方法是在 Microsoft Excel 中打开文件并重新另存为制表符分隔文件。但这将无法正常工作,因为 Excel 无法正确识别随机数量的空格分隔符。以下是我为读取行列格式的制表符分隔的文本文件所做的代码,但我需要帮助来解决我机器生成的文件的问题。

string filename = @"D:\EMS_DATA\firstfile.txt";
string[] lines = File.ReadAllLines(filename)
    .Where(arg => !string.IsNullOrWhiteSpace(arg)).ToArray();
string[] cols = lines[0].Trim()
    .Split(new[] {'\t'}, StringSplitOptions.RemoveEmptyEntries);

int linesss = 1;
foreach (string line in lines.Skip(1))
{
    string[] cells = line.Trim()
        .Split(new[] {'\t'}, StringSplitOptions.RemoveEmptyEntries);
    for (int counter = 0; counter < cols.Length; counter++)
    {
        string cellValue = "N/A";
        if(counter < cells.Length)
            cellValue = cells[counter];
        Console.WriteLine(
            "values at row {0} column {1} are {2} : {3}", 
            line, 
            counter, 
            cols[counter], 
            cellValue);
    }

    linesss++;
}

文本文件格式为

firstname  lastname  salary  age
sasi   kiran    88000   32
ravi   kiran    92000   23
jafer  sharif   34000   45
kiran  bedi     45000   34

更新: 生成的文本文件格式不正确。我目前的解决方法是在 Microsoft Excel 中打开文件,然后将其再次保存为制表符分隔的文件。我需要可以自动为我执行此操作的代码方面的帮助。

【问题讨论】:

  • 您必须准确解释这个“列行格式”文件的格式是什么,例如举个例子
  • 使用 .NET TextFieldParser 类。你喜欢它的 TextFieldType 设置为 FixedWidth 和它的 FieldWidths 属性。
  • @Marc B 我更新了我的问题
  • @Hans Passant 能否提供 TextFieldParser 类的代码
  • 为什么不直接使用 Regex.Match() 和模式“(\\w+)|(\\d+)”?

标签: c# .net regex


【解决方案1】:

更新答案:

这里有一个潜在的问题。如果您将制表符分隔的文件与使用空格的文件进行比较(使用您的示例,我假设它与机器生成的文件完全相同),则没有明显的间距模式。见下文:

//These have spaces
firstname  lastname  salary  age
sasi   kiran    88000   32
ravi   kiran    92000   23
jafer  sharif   34000   45
kiran  bedi     45000   34

//These have tabs
firstname   lastname    salary  age
sasi    kiran   88000   32
ravi    kiran   92000   23
jafer   sharif  34000   45
kiran   bedi    45000   34

除非你能找到一个模式,否则这基本上意味着任何单元格都不能包含空格,否则你将无法拆分。我建议你尝试在那里找到一个模式。

对于代码本身,我借此机会稍微修改了您的代码,并加入了正则表达式。在这种情况下使用正则表达式更有意义。

代码:

        string filename = @"C:\firstfile.txt";

        //Regex objects to detect every range of spaces between 1-infinite, OR one tab.
        Regex regx = new Regex(@"[\s]+|[\t]", RegexOptions.Compiled);

        //Read all lines of a file, one line per index
        string[] lines = File.ReadAllLines(filename);

        //Create multi-dimensional List array
        List<List<string>> sheet = new List<List<string>>();

        //Split each line in lines by column, and you end up with a multi-dimensional array.
        //Makes it look like an excel sheet. [Row][Column]
        sheet.AddRange(lines.Select(x => new List<string>(regx.Split(x).ToList())));

        //Start from rowIndex = 1, as 0 contains the headers
        for (int rowIndex = 1; rowIndex < sheet.Count; rowIndex++)
        {
            for (int colIndex = 0; colIndex < sheet[rowIndex].Count; colIndex++)
            {
                Console.WriteLine("values at row {0} column {1} are {2} : {3}",
                    rowIndex,
                    colIndex,
                    sheet[0][colIndex],
                    sheet[rowIndex][colIndex]
                    );
            }
        }

输出

values at row 1 column 0 are firstname : sasi
values at row 1 column 1 are lastname : kiran
values at row 1 column 2 are salary : 88000
values at row 1 column 3 are age : 32
values at row 2 ...

如果事实证明您的机器生成的代码总是在每个字段之间放置一个大于 1 个空格的最小空格,那么您可以有任何小于该空格数的空格 在实际的“单元格”中。如果是这种情况,请修改正则表达式模式,如下所示:

替换这个:

Regex regx = new Regex(@"[\s]+|[\t]", RegexOptions.Compiled);

与:

Regex regx = new Regex(@"[\s]{2,}|[\t]", RegexOptions.Compiled);

我还想提一下,这就是 CSV 更受欢迎的原因,因为这些文件使用“;”而不是空格。

要将这一切写回到适当的制表符分隔文件中,请使用以下内容:

    string filename_modified = @"C:\modifiedfile.txt";
    File.WriteAllText(filename_modified, String.Join(Environment.NewLine, sheet.Select(x => String.Join("\t", x))));

【讨论】:

  • 我已经修复了它,那是我的错误发布,但我的问题是如何使文本文件选项卡锯齿化以使用此代码。生成的文本文件不是选项卡分隔
  • 必须用制表符分隔吗?你能用 CSV 代替吗?
  • 另外,如果问题是不相关的软件没有正确生成制表符分隔的数据,那么您提供给我们的信息是完全不相关的。
  • 生成的文本文件格式不正确。到目前为止,我所做的是用 microsoft excel 以制表符分隔的方式打开文本文件,然后再次保存为文本文件。然后我使用了上面的代码来处理。我的问题是我们是否有一个代码可以执行我上面所做的手动过程?
  • 嘿没问题。另外要记住的是,如果需要使用迭代的索引,不要使用foreach,而是使用for循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多