1

printstreamで正規表現を置き換えることは可能ですか?

コンソール ウィンドウに表示されるすべてのテキストをログに記録するコードがありますが、ANSI エスケープ コードもログに記録します。

私はこの正規表現"s:\x1B\[[0-9;]*[mK]::g"がそれらを削除することを発見しましたが、それは文字列でのみ機能します。文字列の定数ストリームに正規表現置換を適用し、ANSI エスケープ コードを除外する方法はありますか?

プログラミングに関しては、私はまだ初心者であり、すでにプログラムを構築しているだけです。

編集:

スタックオーバーフローで別の場所で見つけたこのコードがあります。これにより、ログファイルとコンソールに同時にストリーミングできます。

これは私が使用するもので、この後ティーに出します。

Logging tee = new Logging(file, System.out);

.

package com.md_5.mc.chat;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

public class Logging extends PrintStream
{
  private final PrintStream second;

  public Logging(OutputStream main, PrintStream second)
  {
    super(main);
    this.second = second;
  }

  public void close()
  {
    super.close();
  }

  public void flush()
  {
    super.flush();
    this.second.flush();
  }

  public void write(byte[] buf, int off, int len)
  {
    super.write(buf, off, len);
    this.second.write(buf, off, len);
  }

  public void write(int b)
  {
    super.write(b);
    this.second.write(b);
  }

  public void write(byte[] b) throws IOException
  {
    super.write(b);
    this.second.write(b);
  }
}
4

3 に答える 3

1

のサブクラスを作成しFilterOutputStreamますRegexOutputStreamwrite(...)このクラスは、(さまざまなメソッドから)書き込まれたすべてのデータをバッファする必要があります。flush()メソッドでは、正規表現を適用してから、結果を基になる に書き込む必要がありますOutputStream

次に、 をインスタンス化してPrintWriterに書き込みますRegexOutputStreamPrintWriterこの方法では、クラスの動作を変更する必要はありません。フィルタリングが不要になった場合は、チェーンから RegexOutStream を削除するだけで、すべてが再び機能します。

PrintWriterの使用方法によっては、これによりRegexOutputStreams バッファーが非常に大きくなる可能性があることに注意してください。自動フラッシュする を作成するPrintWriterと、すべての行とすべてのバイト配列の後にフラッシュされます。詳細については、そのJavaDocを参照してください。

于 2012-07-31T15:18:36.730 に答える
1

問題の印刷ストリームをサブクラス化し、適切なsuperメソッドを呼び出す前に正規表現の置換を実行できますか? 例えば

public void ExampleStream extends PrintStream {

  @Override
  public void print(String s) {
    super(s.replaceAll(ANSI_PATTERN,""));
  }
}
于 2012-07-31T15:08:35.580 に答える
0

クラスのコードは良いアプローチではないと思いますLogging(少なくともそのままでは):

  • PrintStream ソース コードにアクセスできる場合、現在再定義されているメソッドがまったく使用されていないことに気付くかもしれません: PrintStream#print(...) メソッドは textOut#write(...) (再定義された OutputStream ではなく) にデリゲート#書きます(...) )。
  • したがって、出力を効果的にフィルタリングするには、print(String) および print(char[]) メソッドを再定義する必要があります。
  • 回答には、再定義されたメソッドの例がいくつかあります (これをさらに下に含めます)。

あるいは、ANSI コードを除外する PrintStream が必要な場合 (私が最初に理解したように)、FilterOutputStream に実装する方が便利です (mthmulders が示唆するように、再定義する必要があるものは少なくなり、簡単になります)。再利用する):

  • BufferedOutputStreamクラスのコピーを作成します。好きなように名前を付けてください。(例: TrimAnsiBufferedStream )
  • 次に、flushBuffer() メソッドを再定義します。

    private void flushBuffer() throws IOException {
        if (count > 0) {
            String s = new String(buf, 0, count); // Uses system encoding.
            s.replaceAll(ANSI_PATTERN, "");
            out.write(s.getBytes());
            count = 0;
        }
    }
    
  • ANSI を置き換える PrintStream をインスタンス化する必要がある場合は、 を呼び出しnew PrintStream(new TrimAnsiBufferedStream(nestedStream))ます。

  • これはおそらく防弾ではありません (たとえば、エンコード構成で何が起こるか、バッファー サイズが十分に大きくない場合、または printstream のオプションをフラッシュする場合など)、過度に複雑にするつもりはありません。

ところで。kukelekuuk00さん、はじめまして。よくある質問と回答に対するフィードバックを必ずお読みください(私たちはあなたのことを気にかけています、往復してください)。

于 2012-07-31T16:25:03.923 に答える