2010-10-01 83 views
1

有没有什么办法可以将诸如“hello \ r \ n \ world”这样的字符串解释为字符串,其中\ r \ n已被转换为其实际的字面值。解释Java字符串

这种情况是用户键入正则表达式替换表达式并在UI中键入\ r \ n。那得到了逃脱,但我想从中得到实际的解释字符串。

+1

你不能只使用String.replace()吗? – 2010-10-01 23:19:30

+0

\ r \ n除了\ r \ n我宁愿不必手动替换每个可能的\ X文字和\ uXXXX等 – 2010-10-01 23:41:21

回答

1

Apache公用StringEscapeUtils.unescapeJava(...)方法将完成这项工作。虽然从javadoc描述中不清楚,但这些方法处理unicode转义以及“普通”Java String转义。

+0

好吧,这正是我正在寻找的。谢谢!! – 2010-10-02 09:54:13

2

我并不直接熟悉处理这个问题的'简单'方法(即我注意到是否有内置的库可以处理这个问题)。 但是这样做的一个方法是读取关于转义序列的JLS规范并编写一个可以查找和评估每个转义序列的单通解析器。 (检查JLS 3.10.6 Escape Sequences for Character and String Literals)。

现在我知道一个事实,你会很快忘记处理一些古怪事物,例如八进制转义是非常棘手的,因为它允许1,2或3位数字,并且在每种情况下都有不同当它是一个转义时,以及它只是整数时允许的值。

以字符串“\ 431”为例,这是与字符'1'连接的ocal转义'\ 43',因为八进制转义的第一个数字是4,因此不能是完整的三位八进制数值因为它只允许[0-3]作为这种情况下的第一个数字。

大约一年前,我为1.3规范的子集共同编写了一个Java编译器,它的确有转义序列,下面我已经包含了处理转义的代码 - 你应该能够这段代码字面上,因为它是和包括一个实用工具类(也许扔在一个信用,如果你觉得慈善):

private String processCharEscapes(String strVal) { 
    // Loop helpers 
    char[]   chrArr = strVal.toCharArray(); 
    StringBuilder strOut = new StringBuilder(strVal.length()); 
    String   strEsc = ""; // Escape sequence, string buffer 
    Character  chrBuf = null; // Dangling character buffer 

    // Control flags 
    boolean inEscape = false; // In escape? 
    boolean cbOctal3 = true;  // Can be octal 3-digit 

    // Parse characters 
    for(char c : chrArr) { 
     if (!inEscape) { 
      // Listen for start of escape sequence 
      if (c == '\\') { 
       inEscape = true; // Enter escape 
       strEsc = "";  // Reset escape buffer 
       chrBuf = null;  // Reset dangling character buffer 
       cbOctal3 = true; // Reset cbOctal3 flag 
      } else { 
       strOut.append(c); // Save to output 
      } 
     } else { 
      // Determine escape termination 
      if (strEsc.length() == 0) { // First character 
       if (c >= 48 && c <= 55) { // c is a digit [0-7] 
        if (c > 51) { // c is a digit [4-7] 
         cbOctal3 = false; 
        } 
        strEsc += c; // Save to buffer 
       } else { // c is a character 
        // Single-character escapes (will terminate escape loop) 
        if (c == 'n') { 
         inEscape = false; 
         strOut.append('\n'); 
        } else if(c == 't') { 
         inEscape = false; 
         strOut.append('\t'); 
        } else if(c == 'b') { 
         inEscape = false; 
         strOut.append('\b'); 
        } else if(c == 'r') { 
         inEscape = false; 
         strOut.append('\r'); 
        } else if(c == 'f') { 
         inEscape = false; 
         strOut.append('\f'); 
        } else if(c == '\\') { 
         inEscape = false; 
         strOut.append('\\'); 
        } else if(c == '\'') { 
         inEscape = false; 
         strOut.append('\''); 
        } else if(c == '"') { 
         inEscape = false; 
         strOut.append('"'); 
        } else { 
         // Saw illegal character, after escape character '\' 
         System.err.println(ErrorType.SYNTAX_ERROR, "Illegal character escape sequence, unrecognised escape: \\" + c); 
        } 
       } 
      } else if(strEsc.length() == 1) { // Second character (possibly) 
       if (c >= 48 && c <= 55) { // c is a digit [0-7] 
        strEsc += c; // Save to buffer 
        if (!cbOctal3) { // Terminate since !cbOctal3 
         inEscape = false; 
        } 
       } else { 
        inEscape = false; // Terminate since c is not a digit 
        chrBuf = c;   // Save dangling character 
       } 
      } else if(strEsc.length() == 2) { // Third character (possibly) 
       if (cbOctal3 && c >= 48 && c <= 55) { 
        strEsc += c;  // Save to buffer 
       } else { 
        chrBuf = c;   // Save dangling character 
       } 
       inEscape = false;  // Will always terminate after third character, no matter what 
      } 

      // Did escape sequence terminate, at character c? 
      if (!inEscape && strEsc.length() > 0) { 
       // strEsc is legal 1-3 digit octal char code, convert and add 
       strOut.append((char)Integer.parseInt(strEsc, 8)); 

       if (chrBuf != null) { // There was a dangling character 
        // Check for chained escape sequences (e.g. \10\10) 
        if (chrBuf == '\\') { 
         inEscape = true; // Enter escape 
         strEsc = "";  // Reset escape buffer 
         chrBuf = null;  // Reset dangling character buffer 
         cbOctal3 = true; // Reset cbOctal3 flag 
        } else { 
         strOut.append(chrBuf); 
        } 
       } 
      } 
     } 
    } 

    // Check for EOL-terminated escape sequence (special case) 
    if (inEscape) { 
     // strEsc is legal 1-3 digit octal char code, convert and add 
     strOut.append((char)Integer.parseInt(strEsc, 8)); 

     if (chrBuf != null) { // There was a dangling character 
      strOut.append(chrBuf); 
     } 
    } 

    return strOut.toString(); 
} 

我希望这可以帮助你。

+0

我是否认为这段代码不涉及Unicode转义?对于此代码的原始用例,这是可以理解的。但是OP对另一个答案的评论表明,他还需要翻译unicode escapes。 – 2010-10-02 03:07:28

+0

啊,是的,你是对的 - 在答案的最高层,我必须忘记,其中一个减少是我们不支持Unicode。所以确实,在上面没有Unicode支持,所以上面的代码最多只能围绕包含该实现的实现形成框架。太棒了,你抓住了。 :-) – micdah 2010-10-02 05:08:03

+0

感谢您抽出宝贵时间回复并提供代码。顺便说一句,对于unicode,我可以添加我处理unicode转义的代码。 if(c =='\\'){if(i 2010-10-02 10:16:59