iTextSharpでPDFの文字を置換する、のを超簡易版で（C#）

ネットで探しても、あるのか無いのか。作ってみました。
あくまで基本的には、という温かい目で見てください。
簡単そうでなかなか・・・
とりあえず、ASCIIコード、つまり半角英文字と数字・記号が利用できる程度のもので、且つ"ABC"を'AAA'に置換する、という程度のものです。
PDFは漢字については、その文字コード（番号）を半角英数字で記述しています。（バイナリで0Aなら、半角数字で0Aと記述という具合です）
しかも、SJIS・UTF8は指定によりPDF文書ごとに・・・となっているようです。

サーチそのものはCONTENTSの中に出現する文字列をbyte配列の状態で比較しています。
ただ、このプログラムで取得されるのは、制御関係の半角英数字が混じっている長いbyte配列です。なので、制御系とマッチし　てしまわないように5文字以上の長めの単語で使ってください。
ここから、制御の文字列ではない状態のケースのみで、マッチするか？という処理をする。というように改造していく感じだと思います。




```csharp
        /// <summary>指定のPDFに、指定の文字列があれば、指定のbyte（初期値は半角SP）で埋めます。</summary>
        static private bool replace_PDF_textCONTENTS_proc(string in_in_filepath, string in_out_filepath, string in_moto_text,byte in_埋めるbyte ,int in_replace_count = 0)
        {
            if (File.Exists(in_in_filepath) == false)
                return false;

            byte[] tmp_sarch_bytes = System.Text.Encoding.UTF8.GetBytes(in_moto_text);
            PdfReader reader = new PdfReader(in_in_filepath);
            for (int i番 = 1; i番 <= reader.NumberOfPages; i番++)
            {
                PdfDictionary dict = reader.GetPageN(i番);
                PdfObject object2 = dict.GetDirectObject(PdfName.CONTENTS);
                if (object2 is PRStream)
                {
                    PRStream stream = (PRStream)object2;
                    byte[] data = PdfReader.GetStreamBytes(stream);

                    int match_count = 0;
                    for (int i = 0; i < data.Length - tmp_sarch_bytes.Length; i++)
                    {
                        byte type_by = data[i];



                        Func<bool> get_match = () =>
                        {
                            for (int p = 0; p < tmp_sarch_bytes.Length; p++)
                            {
                                if (data[i + p] != tmp_sarch_bytes[p])
                                    return false;
                            }
                            return true;
                        };
                        bool is_match = get_match();
                        if (is_match == false)
                            continue;
                        //
                        // 合致したケース
                        match_count++;
                        for (int p = 0; p < tmp_sarch_bytes.Length; p++)
                        {
                            data[i + p] = in_埋めるbyte;
                        }
                        if (in_replace_count != 0 && match_count == in_replace_count)   // 置換の回数指定があれば、その回数の置換で終了します。
                            break;
                    }

                    stream.SetData(data);
                }
            }

            try
            {
                PdfStamper stamper = new PdfStamper(reader, new FileStream(in_out_filepath, FileMode.Create));
                stamper.Close();
                reader.Close();
            }
            catch (Exception ex)
            {
            }
            finally
            {
                reader.Close();
            }

            return true;
        }
```



##以下のは、異なる長さに置換できるのですが、置換後を""としたところ問題がありました。
WindowsのPDFビュワーでは問題なく表示できます。
ですが、PDFダイレクト対応プリンタ(Ricoh MPC5503)ではエラーで印刷できませんでした。
上の"ABC"を"AAA"にする、置き換え型では大丈夫でした。
文字列が無い、というのが厳密なPDF仕様ではアウトなのかもしれません・・・


```csharp
        static private bool replace_PDF_textCONTENTS_proc(string in_in_filepath, string in_out_filepath, string in_moto_text,string in_new_text)
        {
            if (File.Exists(in_in_filepath) == false)
                return false;

            byte[] new_bytes = System.Text.Encoding.UTF8.GetBytes(in_new_text);

            byte[] tmp_sarch_bytes = System.Text.Encoding.UTF8.GetBytes(in_moto_text);
            PdfReader reader = new PdfReader(in_in_filepath);
            for (int page番号 = 1; page番号 <= reader.NumberOfPages; page番号++)   // このpage番号は1オリジンです
            {
                PdfDictionary dict = reader.GetPageN(page番号);
                PdfObject object2 = dict.GetDirectObject(PdfName.CONTENTS);
                if (object2 is PRStream)
                {
                    PRStream stream = (PRStream)object2;
                    byte[] data = PdfReader.GetStreamBytes(stream);
                    List<byte> new_data = new List<byte>();
                    //
                    // 制御の文字列（オペレータ）は以下に詳しく書かれています。
                    // http://www.kobu.com/docs/pdf/pdfxhand.htm
                    string debug_text_UTF8 = System.Text.Encoding.UTF8.GetString(data);
                    string debug_text_Unicode = System.Text.Encoding.Unicode.GetString(data);

                    int match_count = 0;
                    for (int i = 0; i < data.Length - tmp_sarch_bytes.Length; i++)
                    {
                        byte type_by = data[i];
                        char type_c = (char)type_by;


                        Func<bool> get_match = () =>
                        {
                            for (int p = 0; p < tmp_sarch_bytes.Length; p++)
                            {
                                if (data[i + p] != tmp_sarch_bytes[p])
                                    return false;
                            }
                            return true;
                        };
                        bool is_match = get_match();
                        if (is_match == false)
                        {
                            new_data.Add(data[i]);
                            continue;
                        }

                        //
                        // 合致したケース
                        match_count++;
                        new_data.AddRange(new_bytes);
                        i += tmp_sarch_bytes.Length;
                    }
                    //byte[] set_data = ;
                    stream.SetData(new_data.ToArray());
                }
            }

            try
            {
                PdfStamper stamper = new PdfStamper(reader, new FileStream(in_out_filepath, FileMode.Create));
                stamper.Close();
                reader.Close();
            }
            catch(Exception ex)
            {
            }

            reader.Close();

            return true;
        }
```