tags:

views:

337

answers:

6

Is there a Java method that works like Python's repr? For example, assuming the function were named repr,

"foo\n\tbar".repr()

would return

"foo\n\tbar"

not

foo
        bar

as toString does.

A: 

If you're only going to be using this on strings, in a pinch you could just write a method that goes through the string and replaces special characters (for whatever definition of "special" you want) with their escape codes. That's what I would do. (I did a quick search and nothing came up on Google, so it might be faster to just write the method than to hunt for an existing implementation)

David Zaslavsky
A: 

This will do it, but it's a bit of a hack, it uses StringUtils and replaceEach from Common Lang to achieve a simple replace:

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);
Jon
+1  A: 

If there were such a method, it would make writing quines in Java really easy, because it would solve the problem of escaping the quotes. Seeing as the simplest quines in Java all require manually inserting the quote character manually with its character code, it is unlikely that such a method exists.

newacct
A: 

don't think there's a specific method -- but this'll solve it without commons lang:

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;
}

}

Nico
+2  A: 

In some projects, I use the following helper function to accomplish something akin to Python's repr for strings:

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();
    }
}

Its main advantage over many of the other solutions given here is, that it does not filter only a limited set of non-printable characters (like those replace-based solutions), but simply all non-printable ASCII characters. Some of it could have been written slightly nicer, but it actually does its job...

Note, that like the Python function, this one will surround the string with quotes. If you do not want that, you will have to eliminate the append('"') calls before and after the while loop.

Dirk
A: 

It appears that Jython already does this. You could, in theory, include the Jython jar, startup an interpreter, and actually run repr(object) on the object in question. Probably more overhead than you want, but does exactly what you describe.

If you want to embed the Jython interpreter in your application, consider http://wiki.python.org/jython/JythonFaq/EmbeddingJython .

Jason R. Coombs