Я использую URLDecoder для декодирования строки:
import java.net.URLDecoder;
URLDecoder.decode("%u6EDA%u52A8%u8F74%u627F", StandardCharsets.UTF_8.name());
Что приводит к краху
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)
Кажется, что %u6
и %u8
не разрешены в строке. Я пытался прочитать, что это за символы, но безуспешно. Я нашел строку в наборе данных в поле под названием «поле заголовка страницы». Поэтому я подозреваю, что это закодированные символы, я просто не знаю, какая кодировка. Кто-нибудь знает, что это за символы и какую кодировку я должен использовать для их успешного декодирования?
А, посмотри сюда: Нестандартные реализации.
О, это действительно имеет смысл! Спасибо!
Похоже на нестандартная кодировка на основе UTF-16 "滚动轴承", что по-китайски означает "подшипники".
Я бы предложил просто .replaceAll
%u
с помощью обратной косой черты, а затем использовать StringEscapeUtils
из Apache Commons:
import org.apache.commons.lang3.StringEscapeUtils
val unescapedJava = StringEscapeUtils.unescapeJava(str.replaceAll("%u", "\\u"))
URLDecoder.decode(unescapedJava, StandardCharsets.UTF_8.name())
Это должно обрабатывать оба вида экранирования:
%
, за которыми следуют цифры, не затрагиваются заменой и unescapeJava
%u
обрабатываются особым образом (заменяются на \u
) и устраняются на первом этапе.Если (только если) вы абсолютно уверены, что кодовые точки все закодировались таким образом, то можно обойтись без StringEscapeUtils
:
new String(
"%u6EDA%u52A8%u8F74%u627F"
.replaceAll("%u", "")
.grouped(4)
.map(Integer.parseInt(_, 16).toChar)
.toArray
)
который производит
res: String = 滚动轴承
но я бы посоветовал против этого, потому что этот метод сломается для
входные данные, такие как "%u6EDA%u52A8%u8F74%u627Fcafebabe"
, содержащие неэкранированные символы.
Лучше использовать надежный библиотечный метод, который обрабатывает все крайние случаи.
Да, есть и другие строки, декодированные с помощью URL. Спасибо за внимание.
@Sahand В конце концов, я сохранил шаг с URLEncoder, я думаю, что может быть два случая: стандартный и нестандартный. Сейчас я как бы объединил оба решения.
@Sahand А, спасибо... Я знаю, я забыл об этом u
уже три раза подряд, извините. Спасибо. Я думаю, что это должно быть правильно сейчас?
Ваша строка "%u6EDA%u52A8%u8F74%u627F"
является синтаксически неверным как строка в кодировке URL.
Согласно javadoc URLDecoder.decode и
Википедия:Процентное кодирование каждые
%
должны следовать две шестнадцатеричные цифры.
Может быть, вы хотели использовать "\u6EDA\u52A8\u8F74\u627F"
вместо. Это была бы синтаксически правильная строка Java (имеющая 4
шестнадцатеричных экранированных символов Юникода) и эквивалентен "滚动轴承"
.
Но по-прежнему не имеет смысла декодировать URL-адрес этой строки.
Поэтому я предполагаю, что ошибка уже произошла на стороне кодирование,
который создал эту искаженную строку в кодировке URL в первую очередь.
Похоже на неудачную попытку закодировать "滚动轴承", что по-китайски означает "подшипники". Как вы думаете, почему он вообще закодирован в URL?