Java эквивалент Python repr ()? - PullRequest
       4

Java эквивалент Python repr ()?

23 голосов
/ 29 августа 2009

Есть ли метод Java, который работает как repr Python? Например, предполагая, что функция была названа repr,

"foo\n\tbar".repr()

вернется

"foo\n\tbar"

не

foo
        bar

как toString.

Ответы [ 9 ]

8 голосов
/ 29 августа 2009

В некоторых проектах я использую следующую вспомогательную функцию для выполнения чего-то похожего на repr 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();
    }
}

Его главное преимущество перед многими другими решениями, приведенными здесь, состоит в том, что он не фильтрует только ограниченный набор непечатаемых символов (например, решения, основанные на замене ), но просто все не печатные символы ASCII. Некоторые из них могли бы быть написаны немного лучше, но на самом деле они делают свою работу ...

Обратите внимание: эта функция, подобно функции Python, будет окружать строку кавычками. Если вы этого не хотите, вам придется исключить вызовы append ('' ') до и после цикла while .

5 голосов
/ 10 сентября 2013

Java не имеет функции repr, но repr обеспечил вас (полное раскрытие: я являюсь автором repr).

3 голосов
/ 30 мая 2014

Используйте статический метод escapeJava из Commons Lang StringEscapeUtils class.

String repr = "\"" + StringEscapeUtils.escapeJava(myString) + "\"";
1 голос
/ 29 августа 2009

не думаю, что есть какой-то конкретный метод - но это решит его без общего языка:

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

}

1 голос
/ 29 августа 2009

Это будет сделано, но это немного хакерство, оно использует StringUtils и replaceEach из Common Lang для простой замены:

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 голосов
/ 29 августа 2015

Если вы используете Groovy , он предоставляет StringEscapeUtils класс , аналогичный Apache Commons Lang:

StringEscapeUtils.escapeJava("foo\n\tbar")
0 голосов
/ 30 августа 2009

Похоже, что Jython уже делает это. Теоретически вы можете включить Jar Jar, запустить интерпретатор и запустить repr (объект) для рассматриваемого объекта. Вероятно, больше накладных расходов, чем вы хотите, но делает именно то, что вы описываете.

Если вы хотите встроить интерпретатор Jython в свое приложение, рассмотрите http://wiki.python.org/jython/JythonFaq/EmbeddingJython.

0 голосов
/ 29 августа 2009

Если бы существовал такой метод, он бы действительно облегчил написание квин на Java, поскольку это решило бы проблему экранирования кавычек. Ввиду того, что самые простые quines в Java требуют ручной вставки символа кавычки вручную с его символьным кодом, маловероятно, что такой метод существует.

0 голосов
/ 29 августа 2009

Если вы собираетесь использовать это только для строк, в крайнем случае вы можете просто написать метод, который проходит через строку и заменяет специальные символы (для любого определения «специального», которое вы хотите) их escape-кодами. Это то, что я бы сделал. (Я сделал быстрый поиск, и в Google ничего не вышло, поэтому, возможно, было бы быстрее просто написать метод, чем искать существующую реализацию)

...