无法将unicode符号转换为西里尔字母

4le*_*x1v 4 unicode scala escaping spray spray-json

我有一大堆的文件中的Apache Lucene的坚持与俄罗斯的一些名字,当我试图把它们打印出来,它看起来像这样"\u0410\u0441\u043f\u0430\u0440",但不是在西里尔符号.该项目在Scala.我试图用Apache Commons unescapeJava方法解决这个问题,但它没有帮助.还有其他选择吗?

更新: 使用Spray框架编写项目并像这样返回json.

{
  "id" : 0,
  "name" : "\u0410\u0441\u043f\u0430\u0440"
}
Run Code Online (Sandbox Code Playgroud)

Rég*_*les 8

我将尝试确切地推断出你在做什么.你正在使用Spray,所以我认为你正在使用它的json库"spray-json"

所以我想你有一些实例spray.json.JsObject,你在问题中发布的内容是你在打印这个实例时得到的输出.你的json对象是正确的,name字段的值没有嵌入转义,它实际上是转换为转义为转义某些unicode字符的字符串.

请参阅printString此处的定义:https: //github.com/spray/spray-json/blob/master/src/main/scala/spray/json/JsonPrinter.scala

我还假设当你尝试使用时unescapeJava,你将它应用于name字段的值,创建一个新的spray.json.JsObject实例,然后像以前一样打印.鉴于你的json对象实际上没有任何转义,这绝对没有任何东西,然后在打印它时打印机像以前那样进行转义,然后你又回到原点.

作为旁注,值得一提的是json规范没有规定如何编码字符:它们可以存储为文字值,也可以存储为unicode转义符.例如,字符串"abc"可以被描述为just "abc"或as "\u0061\u0062\u0063".两种形式都是正确的.恰巧喷涂json的作者决定将后一种形式用于所有非ascii字符.

所以现在你问,我该怎么做才能解决这个问题?你可以问喷雾JSON笔者补充一点,让您可以指定不希望任何Unicode逃逸的选项.但我想你现在想要一个解决方案.

最简单的方法是将对象转换为字符串(通过JsValue.toStringJsValue.compactPrintJsValue.prettyPrint),然后将结果传递给unescapeJava.至少这会让你回到你的西里尔文原文字符.但这有点严重,实际上非常危险,因为某些字符在字符串文字中不安全.例如:\n将被转移到实际的回归,并且\u0022将被转义为".您可以轻松地看到它将如何破坏您的json文档.但至少它可以证实我的理论(记住我一直在假设你究竟在做什么).

现在进行适当的修复:您可以简单地扩展JsonPrinter和覆盖其printString方法以删除unicode转义.像这样(未经测试):

trait NoUnicodeEscJsonPrinter extends JsonPrinter {
  override protected def printString(s: String, sb: StringBuilder) {
    @tailrec
    def printEscaped(s: String, ix: Int) {
      if (ix < s.length) {
        s.charAt(ix) match {
          case '"' => sb.append("\\\"")
          case '\\' => sb.append("\\\\")
          case x if 0x20 <= x && x < 0x7F => sb.append(x)
          case '\b' => sb.append("\\b")
          case '\f' => sb.append("\\f")
          case '\n' => sb.append("\\n")
          case '\r' => sb.append("\\r")
          case '\t' => sb.append("\\t")
          case x => sb.append(x)
        }
        printEscaped(s, ix + 1)
      }
    }
    sb.append('"')
    printEscaped(s, 0)
    sb.append('"')
  }
}

trait NoUnicodeEscPrettyPrinter  extends PrettyPrinter with NoUnicodeEscJsonPrinter
object NoUnicodeEscPrettyPrinter extends NoUnicodeEscPrettyPrinter

trait NoUnicodeEscCompactPrinter   extends CompactPrinter  with NoUnicodeEscJsonPrinter
object NoUnicodeEscCompactPrinter  extends NoUnicodeEscCompactPrinter
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

val json: JsValue = ...
val jsonString: String = NoUnicodeEscPrettyPrinter( json )
Run Code Online (Sandbox Code Playgroud)

jsonString 将以漂亮的打印格式包含您的json文档,并且没有任何unicde转义.