2

例子

如果我有一个包含这些行的文本文件:

  1. 猫喵了一声。
  2. 狗叫了起来。
  3. 猫跑上一棵树。

我希望得到一个像这样的行和列矩阵:

   0 1 2 3 4 5 6 7 8 9 
0| t-h-e- -c-a-t- -m-e-o-w-e-d-.- - - - - - - -
1| t-h-e- -d-o-g- -b-a-r-k-e-d-.- - - - - - - -
2| t-h-e- -c-a-t- -r-a-n- -u-p- -a- -t-r-e-e-.-

然后我想查询这个矩阵来快速确定文本文件本身的信息。例如,我很快就能判断列“0”中的所有内容是否都是“t”(它是)。

我意识到这似乎是一件奇怪的事情。我试图最终(除其他外)确定各种文本文件是否是固定宽度分隔的,而没有任何关于文件的先验知识。我也想用这个矩阵来检测模式。

将通过此的实际文件非常大。

谢谢!

4

4 回答 4

1

“我试图最终(除其他外)确定各种文本文件是否是固定宽度的(...)”

如果是这样,你可以试试这个:

public bool isFixedWidth (string fileName)
{
    string[] lines = File.ReadAllLines(fileName);

    int length = lines[0].Length;
    foreach (string s in lines)
    {
        if (s.length != Length)
        {
            return false;
        }
    }
    return true;
}

获得该lines变量后,您可以访问任何字符,就像它们在矩阵中一样。喜欢char c = lines[3][1];。但是,不能硬保证所有行的长度都相同。如果您愿意,可以将它们填充为与最长的长度相同的长度。

还,

“我将如何查询以获取包含所有行的空格字符的所有列的列表(例如)”

你可以试试这个:

public bool CheckIfAllCharactersInAColumnAreTheSame (string[] lines, int colIndex)
{
    char c = lines[0][colIndex];
    try
    {
        foreach (string s in lines)
        {
            if (s[colIndex] != c)
            {
                return false;
            }
        }
        return true;
    }
    catch (IndexOutOfRangeException ex)
    {
        return false;
    }
}
于 2013-05-27T22:03:57.743 回答
1

例如,我很快就能判断列“0”中的所有内容是否都是“t”(它是)。

int column = 0;
char charToCheck = 't';

bool b = File.ReadLines(filename)
             .All(s => (s.Length > column ? s[column] : '\0') == charToCheck);
于 2013-05-27T21:44:17.660 回答
1

您可以做的是读取文本文件的第一行并将其用作掩码。将下一行与掩码进行比较,并从掩码中删除与同一位置的字符不同的每个字符。处理完所有行后,您将获得一个分隔符列表。

顺便说一句,代码不是很干净,但我认为这是一个很好的入门。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace DynamicallyDetectFixedWithDelimiter
{
    class Program
    {
        static void Main(string[] args)
        {
            var sr = new StreamReader(@"C:\Temp\test.txt");

            // Get initial list of delimiters
            char[] firstLine = sr.ReadLine().ToCharArray();
            Dictionary<int, char> delimiters = new Dictionary<int, char>();
            for (int i = 0; i < firstLine.Count(); i++)
            {
                delimiters.Add(i, firstLine[i]);
            }

            // Read subsequent lines, remove delimeters from 
            // the dictionary that are not present in subsequent lines
            string line;
            while ((line = sr.ReadLine()) != null && delimiters.Count() != 0)
            {
                var subsequentLine = line.ToCharArray();
                var invalidDelimiters = new List<int>();

                // Compare all chars in first and subsequent line
                foreach (var delimiter in delimiters)
                {
                    if (delimiter.Key >= subsequentLine.Count())
                    {
                        invalidDelimiters.Add(delimiter.Key);
                        continue;
                    }

                    // Remove delimiter when it differs from the 
                    // character at the same position in a subsequent line
                    if (subsequentLine[delimiter.Key] != delimiter.Value)
                    {
                        invalidDelimiters.Add(delimiter.Key);
                    }
                }
                foreach (var invalidDelimiter in invalidDelimiters)
                {
                    delimiters.Remove(invalidDelimiter);
                }
            }

            foreach (var delimiter in delimiters)
            {
                Console.WriteLine(String.Format("Delimiter at {0} = {1}", delimiter.Key, delimiter.Value));
            }

            sr.Close();
        }
    }
}
于 2013-05-28T00:20:33.480 回答
0

由于尚不清楚您到底在哪里遇到困难,因此这里有一些建议。

将文件作为字符串读取,每行一个:

string[] lines = File.ReadAllLines("filename.txt");

从行中获取一个锯齿状的字符数组(矩阵)(这一步似乎没有必要,因为字符串可以像字符数组一样被索引):

char[][] charMatrix = lines.Select(l => l.ToCharArray()).ToArray();

示例查询:第 0 列中的每个字符是否都是“t”:

bool allTs = charMatrix.All(row => row[0] == 't');
于 2013-05-27T21:55:14.497 回答