使用LINQ逐字读取文本文件

3

我正在学习LINQ,想要使用LINQ逐字读取一个文本文件(比如说一本电子书)。

以下是我的尝试:

static void Main()
        {
            string[] content = File.ReadAllLines("text.txt");

            var query = (from c in content
                         select content);

            foreach (var line in content)
            {
                Console.Write(line+"\n");
            }

        }

这段代码逐行读取文件。如果我将ReadAllLines更改为ReadAllText,则文件将逐字读取。

有什么想法吗?

6个回答

3
string[] content = File.ReadAllLines("text.txt");
var words=content.SelectMany(line=>line.Split(' ', StringSplitOptions.RemoveEmptyEntries));
foreach(string word in words)
{
}

您需要添加所需的任何空格字符。使用StringSplitOptions处理连续的空格比我最初使用的Where子句更为清晰。

在 .net 4 中,您可以使用File.ReadLines进行延迟评估,从而在处理大文件时降低RAM使用率。


问题在于下一行的单词会紧贴着上一行的最后一个单词而没有空格。 - Deepak
为什么会有问题?ReadAllLines函数应该已经将它们分开了。然后SelectMany进一步分割每行。而Where子句处理连续的空格。 - CodesInChaos
我认为最好是使用new Regex(@"[^\w'-]")来分割字符串,以捕获大多数非单词字符,但保持'和-在单词内部不变。如果你不使用.NET 4,你也可以从TextReader中编写自己的惰性读取行代码,如: for(string line = rdr.ReadLine(); line != null; line = rdr.ReadLine())yield return line; - Jon Hanna

1
string str = File.ReadAllText();
char[] separators = { '\n', ',', '.', ' ', '"', ' ' };    // add your own
var words = str.Split(separators, StringSplitOptions.RemoveEmptyEntries);

StringSplitOptions.RemoveEmptyEntries 对我来说是新的。谢谢。 - CodesInChaos

0
string content = File.ReadAllText("Text.txt");

var words = from word in content.Split(WhiteSpace, StringSplitOptions.RemoveEmptyEntries) 

select word;

你需要像下面这样定义自己的空格字符数组:

List<char> WhiteSpace = { Environment.NewLine, ' ' , '\t'};

这段代码假设标点符号是单词的一部分(比如逗号)。


0

最好使用ReadAllText()读取所有文本,然后使用正则表达式获取单词。使用空格作为分隔符可能会导致一些问题,因为它还会检索标点符号(逗号、句号等)。例如:

Regex re = new Regex("[a-zA-Z0-9_-]+", RegexOptions.Compiled); // You'll need to change the RE to fit your needs
Match m = re.Match(text);
while (m.Success)
{
    string word = m.Groups[1].Value;

    // do your processing here

    m = m.NextMatch();
}

0
以下代码使用迭代器块,因此采用延迟加载。其他解决方案需要在能够迭代单词之前将整个文件加载到内存中。
static IEnumerable<string> GetWords(string path){  

    foreach (var line in File.ReadLines(path)){
        foreach (var word in line.Split(null)){
            yield return word;
        }
    }
}

Split(null)自動刪除空格

使用方法如下:

foreach (var word in GetWords(@"text.txt")){
    Console.WriteLine(word);
}

也可以与标准 Linq 一起使用:

GetWords(@"text.txt").Take(25);
GetWords(@"text.txt").Where(w => w.Length > 3)

当然,出错处理等内容为了学习而被省略了。


-1

你可以写成 content.ToList().ForEach(p => p.Split(' ').ToList().ForEach(Console.WriteLine)) 但这不算是很多的 Linq。


ForEach方法的返回类型是void,这种方法链式调用将无法编译通过。 - guhou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接