2012-07-31 53 views
1

是否可以在打印流中使用正則表達式替換?替換打印流中的文本

我有一段代碼記錄了我的控制檯窗口中顯示的所有文本,但它也記錄了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); 
    } 
} 
+0

你的問題現在解決了嗎?如果是這樣,理想情況下,您應該轉貼該答案並將其標記爲已接受。如果不是,你能解釋這是如何影響你的問題的嗎? – 2012-07-31 15:18:34

+0

@DuncanJones這是我已經存在的代碼,我只是不知道如何編輯printstream(System.out)來將ANSI代碼從輸出流中過濾到我的文件中。 – kukelekuuk00 2012-07-31 16:10:16

+0

我假設,其他假設,你想要一個PrintStream過濾掉ANSI(如開頭所述)。然後在編輯中討論您正在使用的其他代碼(恰好執行輸出重複)。所以只是爲了確定:你想讓你的代碼(打印到兩個輸出)也過濾出正則表達式。你不是嗎? (也許它應該從頭說明更清楚) – Javier 2012-07-31 17:35:48

回答

1

你可以在繼承問題的打印流,並調用適當的方法super之前執行你的正則表達式替換?例如。

public void ExampleStream extends PrintStream { 

    @Override 
    public void print(String s) { 
    super(s.replaceAll(ANSI_PATTERN,"")); 
    } 
} 
+0

有許多口味的印刷和書寫。 print(String)和其他print()方法委託在寫入(String)上。如果重新定義了write(String),會更好,但如果使用print(char [])(例如)就不夠好。 – Javier 2012-07-31 15:24:39

+0

哎呀,對不起,我編輯了答案,我的意思是在我自己的編輯中將文字變成常量。我無法恢復它。 – Javier 2012-07-31 16:35:21

+0

@Javier沒問題,它改善了我的答案。 – 2012-07-31 20:02:42

1

創建創建的FilterOutputStream一個子類,說RegexOutputStream。這個類應該緩衝寫入它的所有數據(來自不同的write(...)方法)。在flush()方法中,它應該應用正則表達式,然後將結果寫入底層OutputStream

接下來,實例化PrintWriter來寫入RegexOutputStream。這樣你就不需要改變PrintWriter類的行爲。如果您不想再進行過濾,您可以將RegexOutStream從鏈中取出,並且所有內容都可以重新使用。

請注意,根據您使用PrintWriter的方式,這可能會導致RegexOutputStream的緩衝區變得相當大。如果您創建PrintWriter進行自動刷新,則會在每行和每個字節數組之後刷新。有關詳細信息,請參閱其JavaDoc

+0

這個想法(作爲FilterOutputStream實現)是正確的,但請求者正在請求更多的東西(新手)。我碰巧有一個相同的想法。 – Javier 2012-07-31 18:54:24

0

我認爲,在Logging類的代碼是不是一個好方法(至少是):

  • 如果您有機會獲得PrintStream的源代碼,你可能會發現,這些方法目前重新定義可能不正在使用:printStream#print(...)方法delegate on textOut#write(...)(不在重新定義的OutputStream#write(...)上)。
  • 因此,您應該重新定義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; 
        } 
    } 
    
  • 當你需要實例化一個PrintStream替換ANSI,調用new PrintStream(new TrimAnsiBufferedStream(nestedStream))

  • 這可能不是防彈的(例如編碼配置可能發生的任何事情,或者緩衝區大小不夠大,或者在打印流中刷新選項),但我不會將其過度複雜化。

順便說一下。歡迎kukelekuuk00。請務必閱讀常見問題和答案反饋(我們關心您,請回復)。

+0

我很難理解如何做到這一點,我對編程頗爲陌生,而且我還沒有做太多的Java編程。 我做了BufferedOutputStream(http://pastie.org/4366500)的副本,但我真的不知道我是否做得對,以及如何使用它。 謝謝,我會。 – kukelekuuk00 2012-07-31 18:05:57

+0

@ kukelekuuk00我不知道如何進一步解釋。雖然我可能會搶奪你一個解決問題的機會,但你有這個課程的代碼:(http://pastie.org/4366578)。希望有幫助 – Javier 2012-07-31 18:23:52

+0

我會仔細看看你做了什麼並繼續。 – kukelekuuk00 2012-07-31 18:39:48