ファイル内のテキストを検索してC#で置き換える方法


157

これまでの私のコード

StreamReader reading = File.OpenText("test.txt");
string str;
while ((str = reading.ReadLine())!=null)
{
      if (str.Contains("some text"))
      {
          StreamWriter write = new StreamWriter("test.txt");
      }
}

テキストを見つける方法は知っていますが、ファイル内のテキストを自分のテキストで置き換える方法はわかりません。


このコメントはヒントとしてのみ考慮してください。ビジュアルスタジオがある場合は、フォルダーをソリューションに含め、ビジュアルスタジオの検索と置換機能を使用できます。幸運
StackOrder

回答:


321

すべてのファイルの内容を読み取ります。と交換してくださいString.Replace。コンテンツをファイルに書き戻します。

string text = File.ReadAllText("test.txt");
text = text.Replace("some text", "new value");
File.WriteAllText("test.txt", text);

5
@WinCoder BTWを使用すると、より複雑な置換を行うことができますRegex.Replace
Sergey Berezovskiy

35
これにより、ファイル全体が一度にメモリに読み込まれます。
Banshee

6
@Banshee Touche '9,000,000行を読み取ろうとしたところ、System out of memory例外がスローされました。
Squ1rr3lz 2015

4
大きなファイルの場合、それはより複雑な問題です。バイトチャンクの読み取り、分析、別のチャンクの読み取りなど
Alexander

6
@アレクサンダー右。1つのチャンクは「... som」で終わり、次のチャンクは「e text ...」で始まります。それをはるかに複雑な問題にします。
djv 2016年

36

あなたが読んでいる同じファイルに書き込むのに苦労するでしょう。簡単な方法の1つは、これを単純に行うことです。

File.WriteAllText("test.txt", File.ReadAllText("test.txt").Replace("some text","some other text"));

あなたはそれをうまくレイアウトすることができます

string str = File.ReadAllText("test.txt");
str = str.Replace("some text","some other text");
File.WriteAllText("test.txt", str);

3
これは簡単ですが、非常に大きなファイルには望ましくありません。(私が反対票を投じたのは私ではありません)
Alvin Wong

3
同意しますが、ファイルの読み取り中はファイルに書き込むことができません。別のファイルに書き出さない限り、後でファイル名を変更して置き換えます。どちらにしても、新しいファイルは、メモリ内かディスク上かに関係なく、ビルド中に別の場所に保存する必要があります。
Flynn1179

@ Flynn1179この例では当てはまりません。できます。やってみよう。私はのReadAllText前にファイルへのアクセスを停止したと思いますWriteAllText。私は自分のアプリでこのテクニックを使用しています。
SteveCinq

知っている; この例は、読み取り中には書き込みません。それが私のポイントでした!
Flynn1179

27

読み取ったすべての行を変更しなくても、出力ファイルに書き込む必要があります。

何かのようなもの:

using (var input = File.OpenText("input.txt"))
using (var output = new StreamWriter("output.txt")) {
  string line;
  while (null != (line = input.ReadLine())) {
     // optionally modify line.
     output.WriteLine(line);
  }
}

この操作を実行したい場合は、一時的な出力ファイルを使用して、最後に入力ファイルを出力に置き換えるのが最も簡単な方法です。

File.Delete("input.txt");
File.Move("output.txt", "input.txt");

(ほとんどのエンコーディングが可変幅であることを考えると、常に同じ長さの置換を行うのは難しいため、テキストファイルの途中で更新操作を実行するのはかなり困難です。)

編集:元のファイルを置き換える2つのファイル操作ではなく、を使用することをお勧めしますFile.Replace("input.txt", "output.txt", null)。(MSDNを参照してください。)


1
VBは2行を変更する必要がありました:input As New StreamReader(filename)While input.Peek()> = 0
Brent

8

テキストファイルをメモリにプルしてから置換を行う必要がある可能性があります。次に、明確に知っている方法でファイルを上書きする必要があります。だからあなたは最初に:

// Read lines from source file.
string[] arr = File.ReadAllLines(file);

YOuはループして、配列内のテキストを置き換えることができます。

var writer = new StreamWriter(GetFileName(baseFolder, prefix, num));
for (int i = 0; i < arr.Length; i++)
{
    string line = arr[i];
    line.Replace("match", "new value");
    writer.WriteLine(line);
}

この方法では、実行できる操作をある程度制御できます。または、単に1行で置換を行うことができます

File.WriteAllText("test.txt", text.Replace("match", "new value"));

これがお役に立てば幸いです。


6

これは私が大きな(50 GB)ファイルでそれをした方法です:

私は2つの方法を試しました。1つ目は、ファイルをメモリに読み込み、正規表現置換または文字列置換を使用する方法です。次に、文字列全体を一時ファイルに追加しました。

最初の方法はいくつかのRegex置換でうまく機能しますが、Regex.ReplaceまたはString.Replaceは、大きなファイルで多くの置換を行うとメモリ不足エラーを引き起こす可能性があります。

2つ目は、一時ファイルを1行ずつ読み取り、StringBuilderを使用して手動で各行を作成し、処理された各行を結果ファイルに追加する方法です。この方法はかなり高速でした。

static void ProcessLargeFile()
{
        if (File.Exists(outFileName)) File.Delete(outFileName);

        string text = File.ReadAllText(inputFileName, Encoding.UTF8);

        // EX 1 This opens entire file in memory and uses Replace and Regex Replace --> might cause out of memory error

        text = text.Replace("</text>", "");

        text = Regex.Replace(text, @"\<ref.*?\</ref\>", "");

        File.WriteAllText(outFileName, text);




        // EX 2 This reads file line by line 

        if (File.Exists(outFileName)) File.Delete(outFileName);

        using (var sw = new StreamWriter(outFileName))      
        using (var fs = File.OpenRead(inFileName))
        using (var sr = new StreamReader(fs, Encoding.UTF8)) //use UTF8 encoding or whatever encoding your file uses
        {
            string line, newLine;

            while ((line = sr.ReadLine()) != null)
            {
              //note: call your own replace function or use String.Replace here 
              newLine = Util.ReplaceDoubleBrackets(line);

              sw.WriteLine(newLine);
            }
        }
    }

    public static string ReplaceDoubleBrackets(string str)
    {
        //note: this replaces the first occurrence of a word delimited by [[ ]]

        //replace [[ with your own delimiter
        if (str.IndexOf("[[") < 0)
            return str;

        StringBuilder sb = new StringBuilder();

        //this part gets the string to replace, put this in a loop if more than one occurrence  per line.
        int posStart = str.IndexOf("[[");
        int posEnd = str.IndexOf("]]");
        int length = posEnd - posStart;


        // ... code to replace with newstr


        sb.Append(newstr);

        return sb.ToString();
    }

0

このコードは私のために働きました

- //-------------------------------------------------------------------
                           // Create an instance of the Printer
                           IPrinter printer = new Printer();

                           //----------------------------------------------------------------------------
                           String path = @"" + file_browse_path.Text;
                         //  using (StreamReader sr = File.OpenText(path))

                           using (StreamReader sr = new System.IO.StreamReader(path))
                           {

                              string fileLocMove="";
                              string newpath = Path.GetDirectoryName(path);
                               fileLocMove = newpath + "\\" + "new.prn";



                                  string text = File.ReadAllText(path);
                                  text= text.Replace("<REF>", reference_code.Text);
                                  text=   text.Replace("<ORANGE>", orange_name.Text);
                                  text=   text.Replace("<SIZE>", size_name.Text);
                                  text=   text.Replace("<INVOICE>", invoiceName.Text);
                                  text=   text.Replace("<BINQTY>", binQty.Text);
                                  text = text.Replace("<DATED>", dateName.Text);

                                       File.WriteAllText(fileLocMove, text);



                               // Print the file
                               printer.PrintRawFile("Godex G500", fileLocMove, "n");
                              // File.WriteAllText("C:\\Users\\Gunjan\\Desktop\\new.prn", s);
                           }

0

私はできる限り単純な転送コードを使用する傾向があり、以下のコードはうまく機能しました

using System;
using System.IO;
using System.Text.RegularExpressions;

/// <summary>
/// Replaces text in a file.
/// </summary>
/// <param name="filePath">Path of the text file.</param>
/// <param name="searchText">Text to search for.</param>
/// <param name="replaceText">Text to replace the search text.</param>
static public void ReplaceInFile( string filePath, string searchText, string replaceText )
{
    StreamReader reader = new StreamReader( filePath );
    string content = reader.ReadToEnd();
    reader.Close();

    content = Regex.Replace( content, searchText, replaceText );

    StreamWriter writer = new StreamWriter( filePath );
    writer.Write( content );
    writer.Close();
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.