Java equivalent of Python repr()?
Asked Answered
F

9

28

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.

Faustino answered 29/8, 2009 at 3:52 Comment(0)
M
10

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.

Measure answered 29/8, 2009 at 17:49 Comment(0)
H
6

Java has no repr-Function, but repr has got you covered (Full disclosure: I am the author of repr).

Houppelande answered 10/9, 2013 at 15:21 Comment(2)
Is it published on Maven?Dogmatic
Not yet. You are the first to ask.Houppelande
K
6

Use the static method escapeJava from the StringEscapeUtils class in Apache Commons Text.

String repr = "\"" + StringEscapeUtils.escapeJava(myString) + "\"";
Keneth answered 30/5, 2014 at 15:0 Comment(0)
S
1

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);
Sparge answered 29/8, 2009 at 5:10 Comment(0)
G
1

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

}

Greenberg answered 29/8, 2009 at 11:41 Comment(0)
E
1

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 .

Elegant answered 29/8, 2009 at 21:8 Comment(0)
N
1

In case you are using Groovy, it provides a similar StringEscapeUtils class as Apache Commons Lang:

StringEscapeUtils.escapeJava("foo\n\tbar")
Nebo answered 29/8, 2015 at 8:52 Comment(0)
M
0

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)

Magellan answered 29/8, 2009 at 4:23 Comment(0)
P
0

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.

Prog answered 29/8, 2009 at 8:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.