2009-08-29 104 views
22

有沒有像Python的repr一樣工作的Java方法?例如,假定功能被命名爲再版,Python等價物repr()?

"foo\n\tbar".repr() 

將返回

"foo\n\tbar"

foo 
     bar

如的toString一樣。

回答

0

如果你只打算使用這對字符串,在緊要關頭,你可以只寫一個經過串去,並與他們的轉義代碼替換特殊字符(「特殊」你想要的任何定義)的方法。這就是我會做的。 (我做了一個快速搜索,Google上沒有任何東西出現,所以寫這個方法可能比尋找現有實現要快)

1

這樣做,但它有點破解,它使用StringUtilsreplaceEach從通用郎實現一個簡單的替換:

String hello = "hello\n\tworld\n\n\t";  
     String replaced = StringUtils.replaceEach(hello, new String[] {"\n", "\t", "\r", "\f"}, 
                 new String[] {"\\n", "\\t", "\\r", "\\f"}); 
     System.out.println("Replaced " + replaced); 
0

如果真有這樣的方法,它將使寫基內斯在Java中很容易的,因爲它會解決逃逸引號的問題。在Java中看到最簡單的quines都需要用字符代碼手動插入引號字符,這種方法不太可能存在。

1

不認爲有什麼具體的方法 - 但是這會解決它沒有公郎鹹平:

public class test { 

public test() throws Exception { 
    byte[] hello = "hello\n\tworld\n\n\t".getBytes(); 
    System.out.println(new String(hexToByte(stringToHex(hello).replaceAll("0a", "5c6e") 
                   .replaceAll("09", "5c74")))); 
} 

public static void main(String[] args) throws Exception { 
    new test(); 
} 

public static String stringToHex(byte[] b) throws Exception { 
    String result = ""; 
    for (int i = 0; i < b.length; i++) { 
     result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1); 
    } 
    return result; 
} 

public static byte[] hexToByte(String s) { 
    int len = s.length(); 
    byte[] data = new byte[len/2]; 
    for (int i = 0; i < len; i += 2) { 
     data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); 
    } 
    return data; 
} 

}

8

在一些項目中,我用下面的輔助函數來完成類似的東西Python的再版字符串:

private static final char CONTROL_LIMIT = ' '; 
private static final char PRINTABLE_LIMIT = '\u007e'; 
private static final char[] HEX_DIGITS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 

public static String toPrintableRepresentation(String source) { 

    if(source == null) return null; 
    else { 

     final StringBuilder sb = new StringBuilder(); 
     final int limit = source.length(); 
     char[] hexbuf = null; 

     int pointer = 0; 

     sb.append('"'); 

     while(pointer < limit) { 

      int ch = source.charAt(pointer++); 

      switch(ch) { 

      case '\0': sb.append("\\0"); break; 
      case '\t': sb.append("\\t"); break; 
      case '\n': sb.append("\\n"); break; 
      case '\r': sb.append("\\r"); break; 
      case '\"': sb.append("\\\""); break; 
      case '\\': sb.append("\\\\"); break; 

      default: 
       if(CONTROL_LIMIT <= ch && ch <= PRINTABLE_LIMIT) sb.append((char)ch); 
       else { 

        sb.append("\\u"); 

        if(hexbuf == null) 
         hexbuf = new char[4]; 

        for(int offs = 4; offs > 0;) { 

         hexbuf[--offs] = HEX_DIGITS[ch & 0xf]; 
         ch >>>= 4; 
        } 

        sb.append(hexbuf, 0, 4); 
       } 
      } 
     } 

     return sb.append('"').toString(); 
    } 
} 

它在這裏的許多人給出的其他解決方案的主要優點,它母鹿s不會僅過濾一組有限的不可打印字符(如替代的解決方案),而只是包含所有不可打印的ASCII字符。其中一些可能會寫得稍微好一點,但它實際上是做它的工作...

請注意,就像Python函數一樣,這個將用引號包圍字符串。如果你不希望出現這種情況,您將收到呼籲消除追加(「「」),後循環。

0

看來,Jython中已經這樣做了,你可以在理論上,包括Jython的罐子,比你想啓動一個解釋,並實際運行有問題的對象再版(對象),也許更多的開銷,但是你描述什麼。

如果你要嵌入的Jython解釋您的應用程序,請考慮http://wiki.python.org/jython/JythonFaq/EmbeddingJython

5

Java沒有repr-Function,但repr已經讓你成爲海灣紅色(全面披露:我是repr的作者)。

+0

是它公佈了Maven的? – Tobia 2014-09-20 14:10:28

+0

還沒有。你是第一個問。 – llogiq 2014-09-25 09:50:21

3

使用來自Commons Lang StringEscapeUtils類的靜態方法escapeJava

String repr = "\"" + StringEscapeUtils.escapeJava(myString) + "\""; 
0

如果您正在使用Groovy的,它提供了一個類似的StringEscapeUtils class例如Apache Commons Lang中:

StringEscapeUtils.escapeJava("foo\n\tbar")