Я попытался декодировать следующую строку,
String str = "AT%26amp%3BT%20Network%20Client%20%u2013%20IBM";
System.out.println(StringEscapeUtils.unescapeHtml(str));
try {
System.out.println("res:"+java.net.URLDecoder.decode(str, "UTF-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Оба метода не работают, как показано ниже,
AT%26amp%3BT%20Network%20Client%20%u2013%20IBM
Exception in thread "main" java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: "u2"
at java.net.URLDecoder.decode(URLDecoder.java:173)
at decrypt.DecryptHtml.main(DecryptHtml.java:19)
Источником строки является скрипт VBS, который использует функцию Escape
. Как я могу декодировать эту строку?
К сожалению, из-за чтения документации, похоже, что Microsoft выполнила ее снова (tm): "non standard xxx", где здесь "xxx" - это "escape-формат".
В частности, в документации к функции VBScript говорится, что:
[...] Юникодовые символы, имеющие значение больше 255, сохраняются с использованием формата% uxxxx.
(Эй, MS: нет такой вещи, как "Unicode characters", это называется кодовыми точками)
Отлично. Таким образом, вам нужна ваша собственная функция декодирования.
К счастью, мы используем Java. И так как эта проприетарная escape-последовательность охватывает только коды кода Unicode на базовой многоязычной плоскости (U + 0000 до U + FFFF), а так как char
является кодовым блоком UTF-16, и поскольку существует 1 к 1 сопоставление между BMP и UTF -16, это делает нашу работу немного легче.
Вот код:
public final class MSUnescaper
{
private static final char PERCENT = '%';
private static final char NONSTANDARD_PCT_ESCAPE = 'u';
private MSUnescaper()
{
}
public static String unescape(final String input)
{
final StringBuilder sb = new StringBuilder(input.length());
final CharBuffer buf = CharBuffer.wrap(input);
char c;
while (buf.hasRemaining()) {
c = buf.get();
if (c != PERCENT) {
sb.append(c);
continue;
}
if (!buf.hasRemaining())
throw new IllegalArgumentException();
c = buf.get();
sb.append(c == NONSTANDARD_PCT_ESCAPE
? msEscape(buf) : standardEscape(buf, c));
}
return sb.toString();
}
private static char standardEscape(final CharBuffer buf, final char c)
{
if (!buf.hasRemaining())
throw new IllegalArgumentException();
final char[] array = { c, buf.get() };
return (char) Integer.parseInt(new String(array), 16);
}
private static char msEscape(final CharBuffer buf)
{
if (buf.remaining() < 4)
throw new IllegalArgumentException();
final char[] array = new char[4];
buf.get(array);
return (char) Integer.parseInt(new String(array), 16);
}
public static void main(final String... args)
{
final String input = "AT%26amp%3BT%20Network%20Client%20%u2013%20IBM";
System.out.println(unescape(input));
}
}
Вывод:
AT&T Network Client – IBM
String str = "AT%26amp%3BT%20Network%20Client%20%[here]u[here]2013%20IBM"
Я думаю, что эта строка недействительна. %u20
недействителен charecter. Если вы удалите u
из своей строки, вы можете закодировать его. Для справки: w3schools html url encodinging
'\u2013'
для представления_
подчеркивания, в строке отсутствует обратная косая черта перед символомu
.%u2013
представлял кодовую точку Unicode 2013, они могут. (И я получаю"–"
, не подчеркивание.)