/** * Replace occurrences of "%ab" with the character represented by the hex value. Strings of * escaped characters are treated as UTF-8 byte sequences and decoded appropriately. */ private static String decode(String s) { int length = s.length(); StringBuilder str = new StringBuilder(length); Matcher matcher = PATTERN.matcher(s); int offset = 0; byte[] bb = null; while (matcher.find(offset)) { int count = matcher.groupCount(); for (int i = 0; i < count; i++) { String match = matcher.group(0); int num = match.length() / 3; if (bb == null || bb.length < num) { bb = new byte[num]; } for (int j = 0; j < num; j++) { int head = j * 3 + 1; int tail = head + 2; bb[j] = (byte) Integer.parseInt(match.substring(head, tail), 16); } try { String text = new String(bb, "UTF-8"); str.append(s.substring(offset, matcher.start())); str.append(text); } catch (UnsupportedEncodingException e) { // NOTE: This should *never* be thrown because all // JVMs are required to support UTF-8. I mean, // the strings in the .class file are all in // a modified UTF-8, for pete's sake! :) } } offset = matcher.end(); } if (offset < length) { str.append(s.substring(offset)); } return str.toString(); }