Ява или Скала. Как преобразовать символы типа \ x22 в строку

2

У меня есть строка, которая выглядит так:

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

Как я мог преобразовать это в читаемый JSON?

Я нашел различные медленные решения, подобные здесь с regEx

Уже пробовали:

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

Например, python имеет простое решение, такое как декодирование из 'string_escape'

Связанный возможный дубликат относится к Python, и мой вопрос касается Java или Scala

Рабочее, но также очень медленное решение, которое я использую сейчас, происходит отсюда:

 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)
}
  • 0
    Вы пробовали что-нибудь? Похоже, никаких исследований для меня!
  • 0
    @Prashant похож на тебя . Я пробовал тот медленный, который связан в описании и других
Показать ещё 4 комментария
Теги:
utf
decode

1 ответ

1
Лучший ответ

\x используется для удаления символов ASCII в Python и других языках. В Scala и Java вы можете использовать \u для выхода из символов Unicode. Поскольку ASCII является подмножеством Unicode (как описано здесь), мы можем использовать unescapeJava метод (в StringEscapeUtils) вместе с некоторой простой замены, чтобы добавить \u бежать характер вместе с 2 - мя ведущими нулями:

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

Вы также можете использовать регулярное выражение, чтобы найти escape-последовательности и заменить их соответствующим символом 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
})

Это кажется более быстрым и не требует внешней библиотеки, хотя она по-прежнему может быть медленной для ваших нужд. Вероятно, он также не охватывает некоторые граничные случаи, но может охватывать простые потребности.

Я определенно не эксперт в этом, поэтому может быть лучший способ справиться с этим.

  • 0
    Спасибо за Ваш ответ! Это работает, но все еще медленнее, чем я использую сейчас. Также replaceAll использует regex, поэтому я попытался использовать replace (), но с такой же низкой производительностью.
  • 0
    @Soloveiko Я обновил ответ более простым решением, которое быстрее, но не настолько надежно. Может дать вам несколько новых идей.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню