Подтвердить что ты не робот

Явный эквивалент Python repr()?

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

"foo\n\tbar".repr()

вернет

"foo\n\tbar"

не

foo
        bar

как toString.

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

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

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

Ответ 4

Это будет сделано, но это немного взломан, он использует 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);

Ответ 5

не думаю, что существует конкретный метод - но это решит его без 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;
}

}

Ответ 6

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

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

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