Estoy usando URLDecoder para decodificar una cadena:
import java.net.URLDecoder;
URLDecoder.decode("%u6EDA%u52A8%u8F74%u627F", StandardCharsets.UTF_8.name());
Lo que conduce a la crisis
Exception in thread "main" java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: "u6"
at java.net.URLDecoder.decode(URLDecoder.java:194)
at Playground$.delayedEndpoint$Playground$1(Playground.scala:45)
at Playground$delayedInit$body.apply(Playground.scala:10)
at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:392)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
at scala.App$class.main(App.scala:76)
at Playground$.main(Playground.scala:10)
at Playground.main(Playground.scala)
Parece %u6
y %u8
no están permitidos en la cadena. He tratado de leer sobre lo que estos símbolos son, pero he tenido éxito. He encontrado la cadena en un conjunto de datos en un campo llamado "campo de título de la página". Así que estoy sospechando que están símbolos codificados, sólo que no sé qué codificación. ¿Alguien sabe lo que estos símbolos son y qué codificación que se debe utilizar para decodificar satisfactoriamente ellos?
Se parece a una no estándar UTF-16-basan codifica de "滚动轴承", que es chino para "rodamientos de bolas".
Yo sugeriría que acaba .replaceAll
%u
por barras invertidas, y luego usar StringEscapeUtils
de Apache Commons:
import org.apache.commons.lang3.StringEscapeUtils
val unescapedJava = StringEscapeUtils.unescapeJava(str.replaceAll("%u", "\\u"))
URLDecoder.decode(unescapedJava, StandardCharsets.UTF_8.name())
Esto debe manejar ambos tipos de escapar:
- Las secuencias de escape normales con
%
seguido de dígitos no son afectados por la sustitución yunescapeJava
- El extraño
%u
son tratados especialmente (sustituye por\u
), y se elimina en la primera etapa.
Si (y sólo si) que esté absolutamente seguro de que todos los puntos de código consiguieron codificados de esta manera, entonces se puede prescindir StringEscapeUtils
:
new String(
"%u6EDA%u52A8%u8F74%u627F"
.replaceAll("%u", "")
.grouped(4)
.map(Integer.parseInt(_, 16).toChar)
.toArray
)
que produce
res: String = 滚动轴承
pero me aconsejo en contra de ella, ya que este método se descomponen para las entradas como "%u6EDA%u52A8%u8F74%u627Fcafebabe"
que contienen caracteres sin escape. Mejor utilizar un método fiable biblioteca que maneja todos los casos de esquina.