J'ai un fichier JSON multiligne avec des enregistrements contenant des caractères spéciaux codés en hexadécimaux. Voici un exemple d'un seul enregistrement JSON:Décodage d'une chaîne avec des caractères spéciaux échappés dans Scala issue
{\x22value\x22:\x22\xC4\xB1arines Bint\xC4\xB1\xC3\xA7 Ramu\xC3\xA7lar\x22}
Cet enregistrement est censé être {"value":"ıarines Bintıç Ramuçlar"}
, par exemple Les caractères '"' sont remplacés par les caractères hexadécimaux \ x22 correspondants et les autres caractères spéciaux Unicode sont remplacés par un ou deux hexadécimaux (par exemple \ xC3 \ xA7 encode ç, etc.)
Je dois convertir des chaînes similaires en Unicode normal chaîne à Scala, alors quand il a produit imprimé {"value":"ıarines Bintıç Ramuçlar"}
sans hexadécimaux
en Python, je peux facilement décoder ces enregistrements avec une ligne de code.
>>> a = "{\x22value\x22:\x22\xC4\xB1arines Bint\xC4\xB1\xC3\xA7 Ramu\xC3\xA7lar\x22}"
>>> a.decode("utf-8")
u'{"value":"\u0131arines Bint\u0131\xe7 Ramu\xe7lar"}'
>>> print a.decode("utf-8")
{"value":"ıarines Bintıç Ramuçlar"}
Mais Scala, je ne peux pas trouver un moyen de décoder J'ai essayé sans succès de le convertir comme ceci:
scala> val a = """{\x22value\x22:\x22\xC4\xB1arines Bint\xC4\xB1\xC3\xA7 Ramu\xC3\xA7lar\x22}"""
scala> print(new String(a.getBytes(), "UTF-8"))
{\x22value\x22:\x22\xC4\xB1arines Bint\xC4\xB1\xC3\xA7 Ramu\xC3\xA7lar\x22}
J'ai essayé aussi URLDecoder comme je l'ai trouvé en solution pour problème similaire (mais avec l'URL):
scala> val a = """{\x22value\x22:\x22\xC4\xB1arines Bint\xC4\xB1\xC3\xA7 Ramu\xC3\xA7lar\x22}"""
scala> print(java.net.URLDecoder.decode(a.replace("\\x", "%"), "UTF-8"))
{"value":"ıarines Bintıç Ramuçlar"}
Il a produit le résultat souhaité pour cet exemple mais ne semble pas sûr pour les champs de texte génériques puisqu'il Conçu pour fonctionner avec les URL et nécessite de remplacer tous les \x
par %
dans la chaîne.
Est-ce que Scala a une meilleure façon de résoudre ce problème?
Je suis nouveau à Scala et sera reconnaissant pour toute aide
MISE À JOUR: J'ai fait une solution personnalisée avec javax.xml.bind.DatatypeConverter.parseHexBinary
. Cela fonctionne pour l'instant, mais il semble lourd et pas du tout élégant. Je pense qu'il devrait y avoir une façon plus simple de faire cela.
Voici le code:
import javax.xml.bind.DatatypeConverter
import scala.annotation.tailrec
import scala.util.matching.Regex
def decodeHexChars(string: String): String = {
val regexHex: Regex = """\A\\[xX]([0-9a-fA-F]{1,2})(.*)""".r
def purgeBuffer(buffer: String, acc: List[Char]): List[Char] = {
if (buffer.isEmpty) acc
else new String(DatatypeConverter.parseHexBinary(buffer)).reverse.toList ::: acc
}
@tailrec
def traverse(s: String, acc: List[Char], buffer: String): String = s match {
case "" =>
val accUpdated = purgeBuffer(buffer, acc)
accUpdated.foldRight("")((str, b) => b + str)
case regexHex(chars, suffix) =>
traverse(suffix, acc, buffer + chars)
case _ =>
val accUpdated = purgeBuffer(buffer, acc)
traverse(s.tail, s.head :: accUpdated, "")
}
traverse(string, Nil, "")
}
Toutes les variantes pour le faire sans regEx? –