代码之家  ›  专栏  ›  技术社区  ›  Artem

Java或Scala。如何将\x22之类的字符转换为字符串

  •  4
  • Artem  · 技术社区  · 8 年前

    我有一个字符串,看起来像这样:

    {\x22documentReferer\x22:\x22http:\x5C/\x5C/pikabu.ru\x5C/freshitems.php\x22}
    

    我发现了不同的缓慢解决方案,如 here with regEx

    已经尝试过:

    URL.decode
    StringEscapeUtils
    JSON.parse // from different libraries 
    

    例如,python有简单的解决方案,比如从 'string_escape'

    链接的可能重复适用于Python,我的问题是关于Java或Scala的

    我现在使用的解决方案是从 here :

     def unescape(oldstr: String): String = {
    val newstr = new StringBuilder(oldstr.length)
    var saw_backslash = false
    var i = 0
    while (i < oldstr.length) {
      {
        val cp = oldstr.codePointAt(i)
        if (!saw_backslash) {
          if (cp == '\\') saw_backslash = true
          else newstr.append(cp.toChar)
        } else {
          if (cp == '\\') {
            saw_backslash = false
            newstr.append('\\')
            newstr.append('\\')
          } else {
            if (cp == 'x') {
              if (i + 2 > oldstr.length) die("string too short for \\x escape")
              i += 1
              var value = 0
              try
                value = Integer.parseInt(oldstr.substring(i, i + 2), 16)
              catch {
                case nfe: NumberFormatException =>
                  die("invalid hex value for \\x escape")
              }
              newstr.append(value.toChar)
              i += 1
            }
            else {
              newstr.append('\\')
              newstr.append(cp.toChar)
            }
            saw_backslash = false
          }
        }
      }
      i += 1
    }
        if (saw_backslash) newstr.append('\\')
        newstr.toString
      }
    
    private def die(msg: String) {
      throw new IllegalArgumentException(msg)
    }
    
    1 回复  |  直到 8 年前
        1
  •  4
  •   Ben Reich    8 年前

    \x 用于在Python和其他语言中转义ASCII字符。在Scala和Java中,您可以使用 \u 转义Unicode字符。由于ASCII是Unicode的子集(如所述 here unescapeJava 方法(in StringEscapeUtils )以及一些简单的替换来添加 \u 转义字符和2个前导零:

    import org.apache.commons.lang3.StringEscapeUtils
    StringEscapeUtils.unescapeJava(x.replaceAll("""\\x""", """\\u00"""))
    

    您还可以使用正则表达式查找转义序列,并将其替换为适当的ASCII字符:

    val pattern = """\\x([0-9A-F]{2})""".r
    
    pattern.replaceAllIn(x, m => m.group(1) match {
      case "5C" => """\\""" //special case for backslash
      case hex => Integer.parseInt(hex, 16).toChar.toString
    })
    

    这似乎更快,并且不需要外部库,但对于您的需求来说,速度仍然可能较慢。它可能也不涵盖某些边缘情况,但可能涵盖简单的需求。

    我绝对不是这方面的专家,所以可能有更好的方法来处理这个问题。

    推荐文章