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

Java or Scala. How to convert characters like \x22 into String

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

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

如何将其转换为可读的 JSON?

我发现了不同的慢速解决方案,例如

已经尝试过:

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)
}

\x用于转义Python等语言的ASCII字符。在 Scala 和 Java 中,您可以使用 \u 来转义 Unicode 字符。由于 ASCII 是 Unicode 的子集(如 here 所述),我们可以使用 unescapeJava 方法(在 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
})

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

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