【问题标题】:Character to String representation字符到字符串表示
【发布时间】:2011-01-08 09:39:15
【问题描述】:

我需要在一组字符串中找到特殊的转义 java 字符(\n、\t、\b 等),然后打印哪些字符串包含哪些特殊字符。因此,在打印时,我想通过字符串“\n”来更改字符值本身,“\n”表示“\n”,“\t”表示“\t”等等。我对所有这种类型的字符都使用了 switch 语句。我想知道是否有一个解决方案不涉及检查每个???

【问题讨论】:

  • 根据我的编译器,\a 不是有效的转义序列...

标签: java


【解决方案1】:

我没有为此找到一个库,但另一方面,我的快速实现看起来并不太糟糕 - 我什至更喜欢它而不是 RegExp ;)

public String unescape(String s) {
    StringBuilder result = new StringBuilder();
    for (char c : s.toCharArray()) {
        result.append(toLiteral(c));
    }
    return result.toString();
}

private String toLiteral(char c) {
    switch (c) {
    case '\n':
        return "\\n";
    case '\t':
        return "\\t";
    case '\r':
        return "\\r";
    case '\f':
        return "\\f";
    case '\b':
        return "\\b";
    case '\'':
        return "\\\'";
    case '\"':
        return "\\\"";
    case '\\':
        return "\\\\";
    default:
        return c;
    }
}

根据我的编译器,这些都是字符串允许的转义序列。

【讨论】:

  • 我认为您不需要使用 '\'' 字符。我认为提问者要求将 '\n' 替换为 "\\n"。
  • 是的,这也是我想出的实现。我想这就是我要使用的。
  • 顺便说一句,"\\\'" 字符串可以简化为 "\\'"'\"' 可以简化为 `'"',因为 ' 不需要在字符串中转义,而 " 不需要' 不需要在字符中转义。
【解决方案2】:

嗯,我不认为正则表达式会让你在一行中完成这个替换,即使是反向引用。问题在于为所有特殊字符注入换行符映射到“\n”等知识。

您当然可以通过一系列 replace() 调用来做到这一点,每个字符一个,但您试图避免这种情况。

你需要相当于 Unix 中的 'tr' 命令,很抱歉我不知道这种方法。

【讨论】:

    【解决方案3】:

    归根结底,无论使用什么方法,都需要查看字符串中的每个字符。您可以像现在一样在循环中显式执行,也可以链接一组 replace() 调用。但是,虽然这些在纸上看起来可能更短,但它们可能需要更长的时间。

    使用replace()

    "\ttest\n\n".replace("\t", "\\t").replace("\n", "\\n")/*…*/;
    

    要循环执行此操作,请查看answer from Andreas_D

    请注意,replace() 方法虽然在纸上更短,但几乎肯定会花费更长的时间来运行,因为它必须循环整个字符串 8 次,一次替换每个转义序列,而手动循环只需要做一次。

    编辑:最初我认为你可以用一个神奇的正则表达式来做到这一点,但是你不能在正则表达式中做条件替换,这意味着你只能做相当于替换调用如上所示。鉴于在这种情况下正则表达式会稍微慢一些,我认为这不是一个好的解决方案。

    【讨论】:

      【解决方案4】:

      使用映射来决定替换和 StringBuilder.replace 方法来实际执行替换的不同方法,它看起来更紧凑,我想它在性能上与 switch 版本不远,但肯定会使用更多的内存.

      public class Unescape {
      
          private static final Map<Character, String> replacements = new HashMap<Character, String>(){{
              put('\n',"\\n"); put('\r',"\\r"); put('\t',"\\t"); put('\b',"\\b"); //etc
          }};
      
          public static String unescape(String s) {
              String replace;
              StringBuilder result = new StringBuilder(s);
              for (int i=0; i < result.length(); i++) {
                  replace = replacements.get(result.charAt(i));
                  if (replace!=null) result.replace(i, i+1, replace);
              }
              return result.toString();
          }
      
          public static void main(String[] args) {
      
              System.out.println(unescape("hi\nthere\t\t\tHow are u?"));
      
          }
      
      }
      

      样本的输出是

      你好\n那里\t\t\t你好吗?

      【讨论】:

      • StringBuilders replace 方法总是调用 System.arraycopy。如果在大型输入(文本文件)上使用,这可能会降低性能。另一方面,我喜欢基于地图的解决方案(顺便说一句:应该命名为 REPLACEMENTS,因为常量通常是大写的)
      【解决方案5】:

      你可以使用正则表达式:

      String.replaceAll

      【讨论】:

        【解决方案6】:

        如果您正在寻找更高级的东西,您可以查看this answer

        【讨论】:

          【解决方案7】:

          org.apache.commons.lang.StringEscapeUtils.(un)EscapeJava 方法很可能是你想要做的这两种方式......

          来自brainzzy的回答不是我的:

          https://stackoverflow.com/a/8736043/1130448

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-04-27
            相关资源
            最近更新 更多