如何解析随机空格分隔的文本文件并转换为制表符分隔文件

时间:2015-06-24 17:50:44

标签: c# .net regex

我正在阅读一个巨大的机器生成的,以制表符分隔的文本文件。我在下面提供了以下代码来获取值,但这只有当文本文件以制表符分隔方式时才会起作用,并且结果是外部软件在每个之间使用了随机数量的空格字段。

如何生成将随机空格分隔的文本文件读入制表符分隔文件的代码。我目前的解决方法是在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中打开文件,然后再将其另存为制表符分隔文件。我需要帮助自动执行此操作的代码。

1 个答案:

答案 0 :(得分: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

除非您能找到模式,否则这实际上意味着没有单元格可以包含空格,否则您将无法进行拆分。我建议你试着在那里找到一个模式。

对于代码本身,我借此机会对代码进行了一些修改,并且还包含了Regex。在这种情况下使用正则表达式更有意义。

代码:

        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个空格的每个字段之间放置最小量的空格,那么您可以小于该空格量< / strong>在实际的“细胞”中。如果情况确实如此,请修改正则表达式模式,如下所示:

替换为:

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))));