2010-01-22 72 views
1

我需要在一串字符串中找到特殊的轉義java字符(\ n,\ t,\ b等),然後打印哪些字符串包含哪些特殊字符。所以,在打印時,我想通過字符串「\ n」替換字符值本身爲'\ n',「\ t」爲'\ t'等等。我爲所有這種類型的角色做了switch語句。我想知道是否有解決方案,不涉及檢查每一個?字符串表示

+0

不要忘記\一個! – 2010-01-22 21:28:43

+0

根據我的編譯器,\ a不是一個有效的轉義序列... – 2010-01-22 21:48:00

回答

1

我沒有找到一個圖書館,但另一方面,我的快速實現不看太可怕了 - 我寧願這甚至超過一個RegExp;)

public String unescape(String s) { 
    StringBuilder result = new StringBuilder(); 
    for (char c : s.toCharArray()) { 
     result.append(toLiteral(c)); 
    } 
    return result.toString(); 
} 

private String toLiteral(char c) { 
    switch (c) { 
    case '\n': 
     return "\\n"; 
    case '\t': 
     return "\\t"; 
    case '\r': 
     return "\\r"; 
    case '\f': 
     return "\\f"; 
    case '\b': 
     return "\\b"; 
    case '\'': 
     return "\\\'"; 
    case '\"': 
     return "\\\""; 
    case '\\': 
     return "\\\\"; 
    default: 
     return c; 
    } 
} 

根據我的編譯器,這些都是字符串允許的轉義序列。

+0

我不認爲你需要有'\''字符。我認爲提問者要求用「\\ n」替換'\ n'。 – 2010-01-22 21:54:30

+0

謝謝,我會修改這個例子。有點難以閱讀;) – 2010-01-22 21:56:32

+0

是的,這是我也想出了實現。我想這就是我要用的。 – Omar 2010-01-22 22:09:45

1

嗯,我不認爲正則表達式可以讓你在同一行做替換,甚至反向引用。問題在於將所有特殊字符的換行符映射到「\ n」等知識。

你當然可以用一系列的replace()調用,每個字符一個,但你試圖避免這種情況。

在Unix中你需要相當於'tr'命令,並且我很抱歉地說我不知道​​這種方法。

1

在一天結束時,無論使用什麼方法,都需要查看字符串中的每個字符。您可以像循環一樣在循環中顯式執行,也可以鏈接一組replace()調用。但是,雖然這些在紙上看起來可能較短,但它們可能需要更長的時間。

要做到這一點使用replace()

"\ttest\n\n".replace("\t", "\\t").replace("\n", "\\n")/*…*/; 

在循環中做到這一點,看看answer from Andreas_D

請注意,replace()方法雖然在紙上較短,但幾乎肯定會花費較長的時間運行,因爲它必須循環整個字符串8次,一次替換每個轉義序列,而手動循環只需要做一次。

編輯:起初我還以爲你很可能有一個神奇的正則表達式做到這一點,但你不能做有條件的更換正則表達式,這意味着你只能做上面顯示的替代電話的等價物。鑑於這種情況下regexes會稍微慢一些,我不認爲這是一個好的解決方案。

1

另一種使用映射來決定替換的方法和StringBuilder.replace方法來實際執行替換,它看起來更緊湊一點,我猜它離性能的開關版本不遠,但肯定使用了更多的記憶。

public class Unescape { 

    private static final Map<Character, String> replacements = new HashMap<Character, String>(){{ 
     put('\n',"\\n"); put('\r',"\\r"); put('\t',"\\t"); put('\b',"\\b"); //etc 
    }}; 

    public static String unescape(String s) { 
     String replace; 
     StringBuilder result = new StringBuilder(s); 
     for (int i=0; i < result.length(); i++) { 
      replace = replacements.get(result.charAt(i)); 
      if (replace!=null) result.replace(i, i+1, replace); 
     } 
     return result.toString(); 
    } 

    public static void main(String[] args) { 

     System.out.println(unescape("hi\nthere\t\t\tHow are u?")); 

    } 

} 

樣品的輸出是

喜\ nthere \噸\噸\ tHow是U?

+0

StringBuilders替換方法始終調用System.arraycopy。如果用於大型輸入(文本文件),這可能會導致性能下降。另一方面,我喜歡該解決方案基於在地圖上(順便說一句:應該命名爲REPLACEMENTS,因爲常量通常是大寫) – 2010-01-22 23:48:53