C#在文件中搜索字符串并获取字符串';s线号

C#在文件中搜索字符串并获取字符串';s线号,c#,io,lines,C#,Io,Lines,我一整天都在做这件事,我努力做到这一点,我到处寻找,虽然有类似的问题,但没有答案 我想做什么: 我试图在一个文件中搜索多个字符串并接收行号,这样当用户希望在我的应用程序中更改所述字符串时,我的应用程序就知道用他们的字符串替换哪些行 到目前为止我所尝试的: 我已经尝试了下面的代码,我的尝试是读取文件,然后接收行号,但是它似乎根本不起作用 var lines = File.ReadAllLines(filepath); foreach (var mat

我一整天都在做这件事,我努力做到这一点,我到处寻找,虽然有类似的问题,但没有答案

我想做什么: 我试图在一个文件中搜索多个字符串并接收行号,这样当用户希望在我的应用程序中更改所述字符串时,我的应用程序就知道用他们的字符串替换哪些行

到目前为止我所尝试的: 我已经尝试了下面的代码,我的尝试是读取文件,然后接收行号,但是它似乎根本不起作用

            var lines = File.ReadAllLines(filepath);
            foreach (var match in lines // File.ReadLines(filePath)
                            .Select((text, index) => new { text, lineNumber = index + 1 })
                            .Where(x => x.text.Contains("motd=")))
            {
                lines[match.lineNumber] = "motd=" + textBox1.Text;
                File.WriteAllLines(filepath, lines);
            }
        }
我希望上面的代码能够在文件中找到字符串“motd=”,获取行号并尝试用用户输入的内容重新写入


但是,我收到了这个错误:“
索引超出了数组的界限”

我认为
for
循环在这里更有意义

var lines = File.ReadAllLines(filepath);
for (int i = 0; i < lines.Length; i++)
{
    if(lines[i].Contains("motd="))
    {
        lines[i] = "motd=" + textBox1.Text;
    }
}

File.WriteAllLines(filepath, lines);

你在每一次迭代中都写文件,这毫无意义,而做一个select/where/index的事情也很奇怪

既然你在做一个
,其中
你必须迭代每一行,那么为什么不省去麻烦,直接迭代每一行呢

var lines = File.ReadAllLines(filepath);
for(int i = 0; i < lines.Length; i++)
{
    if(lines[i].Contains("motd="))
    {
        lines[i] = "motd=" + textBox1.Text;
    }
}

File.WriteAllLines(filepath, lines);
var lines=File.ReadAllLines(filepath);
对于(int i=0;i
这将更快,使用更少的内存,并且可以处理非常大的文件,但您需要写入一个新文件:

File.WriteAllLines(filepath2,
  File
    .ReadLines(filepath)
    .Select(x=>x.Contains("motd=")?"motd="+TextBox1.Text:x));
它使用ReadLines尽可能地读取每一行,而不是读取整个文件并在一个步骤中将其拆分为几行。因此,它会以文件系统能够读取的速度处理它,处理该行,然后写入结果

完整的替换将如下所示:

var filepath2= Path.GetTempFileName();
File.WriteAllLines(filepath2,
  File
    .ReadLines(filepath)
    .Select(x=>x.Contains("motd=")?"motd="+TextBox1.Text:x));
File.Delete(filepath);
File.Move(filepath2, filepath);
要执行多个值,请执行以下操作:

var filepath2= Path.GetTempFileName();
File.WriteAllLines(filepath2,
  File
    .ReadLines(filepath)
    .Select(x=> {
      if (x.Contains("motd=")) return "motd="+TextBox1.Text;
      if (x.Contains("author=")) return "author="+TextBox2.Text;
      return x;
    }));
File.Delete(filepath);
File.Move(filepath2, filepath);
或者将替换逻辑移动到其自身的功能:

string ReplaceTokens(string src)
{
  if (src.Contains("motd=")) return "motd="+TextBox1.Text;
  if (src.Contains("author=")) return "author="+TextBox2.Text;
  return src;
}
var filepath2= Path.GetTempFileName();
File.WriteAllLines(filepath2,
  File
    .ReadLines(filepath)
    .Select(ReplaceTokens));
File.Delete(filepath);
File.Move(filepath2, filepath);

为什么要在
foreach
中写入文件?您应该只需要在
foreach
之后执行一次。另外,请定义“似乎根本不起作用”。你有例外吗?输出是否不正确?如果是的话,您得到的是什么?与您期望的是什么?我估计,对于找到的每个匹配,它都会替换为其他匹配。这是因为我打算在将来使用多个值,不过我只是测试一下。此外,我还更新了我的原始帖子,其中包含了错误消息和我所期望的。这似乎成功了!非常感谢,特别是快速响应!如果有10-20个额外的值,这是可行的吗?在你之前,我一直在试图找到一个答案,但看起来你的答案要好得多。我的会使用StreamReader和Peek(),但肯定不会比你的好。@TaylaWilson你当然可以添加
else if
语句,或者一个
switch
语句来处理多个情况。文件大约有40行长,每行大约20个字符,这会被认为是一个大文件吗?@TaylaWilson不,那会被认为是额外的小文件。也谢谢你的帮助!你的和朱哈尔的完全一样哈哈!那么快@泰拉·威尔逊,不客气。我想,伟人的想法是一样的!
string ReplaceTokens(string src)
{
  if (src.Contains("motd=")) return "motd="+TextBox1.Text;
  if (src.Contains("author=")) return "author="+TextBox2.Text;
  return src;
}
var filepath2= Path.GetTempFileName();
File.WriteAllLines(filepath2,
  File
    .ReadLines(filepath)
    .Select(ReplaceTokens));
File.Delete(filepath);
File.Move(filepath2, filepath);