Java 等价于 Python repr()?

Posted

技术标签:

【中文标题】Java 等价于 Python repr()?【英文标题】:Java equivalent of Python repr()? 【发布时间】:2010-11-23 22:30:33 【问题描述】:

有没有像 Python 的 repr 一样工作的 Java 方法?例如,假设函数名为 repr,

"foo\n\tbar".repr()

会回来

"foo\n\tbar"

不是

富
        酒吧

就像 toString 一样。

【问题讨论】:

【参考方案1】:

在某些项目中,我使用以下帮助函数来完成类似于 Python 的字符串 repr 的操作:

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

与此处给出的许多其他解决方案相比,它的主要优势在于,它不仅过滤有限的一组不可打印字符(如那些基于 replace 的解决方案),而且只是过滤所有不可打印的字符。 - 可打印的 ASCII 字符。其中一些本可以写得更好一些,但它确实完成了它的工作......

注意,和 Python 函数一样,这个函数会用引号括住字符串。如果您不希望这样,则必须在 while 循环之前和之后消除 append('"') 调用。

【讨论】:

【参考方案2】:

使用Apache Commons Text 中StringEscapeUtils 类中的静态方法escapeJava

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

【讨论】:

【参考方案3】:

Java 没有 repr-Function,但 repr 已经为您提供了保障(全面披露:我是 repr 的作者)。

【讨论】:

是否在 Maven 上发布? 还没有。你是第一个问的。【参考方案4】:

这样就可以了,但有点小技巧,它使用 Common Lang 的 StringUtils 和 replaceEach 来实现简单的替换:

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】:

如果您只打算在字符串上使用它,那么在紧要关头,您可以编写一个遍历字符串并用转义码替换特殊字符(对于您想要的“特殊”定义)的方法。这就是我会做的。 (我快速搜索了一下,Google 上什么也没找到,所以只写方法可能比寻找现有实现更快)

【讨论】:

【参考方案7】:

如果有这样的方法,在 Java 中编写 quines 将变得非常容易,因为它可以解决转义引号的问题。由于Java中最简单的quines都需要手动插入引号字符及其字符代码,因此不太可能存在这种方法。

【讨论】:

【参考方案8】:

Jython 似乎已经这样做了。理论上,您可以包含 Jython jar,启动解释器,然后在相关对象上实际运行 repr(object)。可能比您想要的更多开销,但完全符合您的描述。

如果您想在应用程序中嵌入 Jython 解释器,请考虑 http://wiki.python.org/jython/JythonFaq/EmbeddingJython。

【讨论】:

【参考方案9】:

如果您使用的是 Groovy,它会提供与 Apache Commons Lang 类似的 StringEscapeUtils class:

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

【讨论】:

以上是关于Java 等价于 Python repr()?的主要内容,如果未能解决你的问题,请参考以下文章

python __str__ , __repr__区别

Java 等价于 Python 字典

Python 等价于 Java StringBuffer?

python repr适用于开发人员,print适用于软件用户

python模块可以有__repr__吗?

C++ 等价于 Python 的带有比较的数组访问 (array[condition] = value)