Преобразование «php unicode» в символ

Как преобразовать так называемый «php unicode» ( ссылка на php unicode ) на обычный символ через Java? Пример \ xEF \ xBC \ xA1 -> A. Есть ли встроенные методы в jdk или я должен использовать regex для этого преобразования?

Этот символ является U + FF21 (FULLWIDTH LATIN CAPITAL LETTER A). Форма PHP (\ xEF \ xBC \ xA1) является кодированной октетом в кодировке UTF-8.

Чтобы декодировать эту последовательность в строку Java (которая всегда является UTF-16), вы должны использовать следующий код:

 // \xEF\xBC\xA1 byte[] utf8 = { (byte) 0xEF, (byte) 0xBC, (byte) 0xA1 }; String utf16 = new String(utf8, Charset.forName("UTF-8")); // print the char as hex for(char ch : utf16.toCharArray()) { System.out.format("%02x%n", (int) ch); } 

Если вы хотите декодировать данные из строкового литерала, вы можете использовать код этой формы:

 public static void main(String[] args) { String utf16 = transformString("This is \\xEF\\xBC\\xA1 string"); for (char ch : utf16.toCharArray()) { System.out.format("%s %02x%n", ch, (int) ch); } } private static final Pattern SEQ = Pattern.compile("(\\\\x\\p{Alnum}\\p{Alnum})+"); private static String transformString(String encoded) { StringBuilder decoded = new StringBuilder(); Matcher matcher = SEQ.matcher(encoded); int last = 0; while (matcher.find()) { decoded.append(encoded.substring(last, matcher.start())); byte[] utf8 = toByteArray(encoded.substring(matcher.start(), matcher.end())); decoded.append(new String(utf8, Charset.forName("UTF-8"))); last = matcher.end(); } return decoded.append(encoded.substring(last, encoded.length())).toString(); } private static byte[] toByteArray(String hexSequence) { byte[] utf8 = new byte[hexSequence.length() / 4]; for (int i = 0; i < utf8.length; i++) { int offset = i * 4; String hex = hexSequence.substring(offset + 2, offset + 4); utf8[i] = (byte) Integer.parseInt(hex, 16); } return utf8; } 

Сначала вам нужно вывести байты из строки в байтовый массив без их изменения, а затем декодировать байтовый массив как строку UTF-8.

Самый простой способ получить строку в массив байтов – это кодировать ее с помощью ISO-8859-1, в которой каждый символ имеет значение unicode меньше 256 байт с тем же значением (или эквивалентным отрицательным)

 String phpUnicode = "\u00EF\u00BC\u00A1" byte[] bytes = phpUnicode.getBytes("ISO-8859-1"); // maps to bytes with the same ordinal value String javaString = new String(bytes, "UTF-8"); System.out.println(javaString); 

редактировать
Вышеописанное преобразует UTF-8 в символ Unicode. Если вы затем захотите преобразовать его в разумный эквивалент ASCII, нет стандартного способа сделать это: но посмотрите на этот вопрос

редактировать
Я предположил, что у вас есть строка, содержащая символы, которые имеют такое же порядковое значение, что и последовательность UTF-8, но вы указываете, что ваша строка буквально содержит escape-последовательность, как в:

 String phpUnicode = "\\xEF\\xBC\\xA1"; 

JDK не имеет встроенных методов для преобразования строк как это, поэтому вам нужно будет использовать собственное регулярное выражение. Поскольку мы в конечном счете хотим преобразовать последовательность байтов utf-8 в String, нам нужно настроить байтовый массив, используя, возможно:

 Pattern oneChar = Pattern.compile("\\\\x([0-9A-F]{2})|(.)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); Matcher matcher = oneChar.matcher(phpUnicode); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); while (matcher.find()) { int ch; if (matcher.group(1) == null) { ch = matcher.group(2).charAt(0); } else { ch = Integer.parseInt(matcher.group(1), 16); } bytes.write((int) ch); } String javaString = new String(bytes.toByteArray(), "UTF-8"); System.out.println(javaString); 

Это приведет к генерации потока UTF-8 путем преобразования последовательностей \ xAB. Этот поток UTF-8 затем преобразуется в строку Java. Важно отметить, что любой символ, который не является частью escape-последовательности, будет преобразован в байт, эквивалентный 8 укусам младшего порядка символа юникода. Это отлично работает для ascii, но может вызвать проблемы с перекодировкой для символов, отличных от ascii.

@McDowell:
Последовательность:

 String phpUnicode = "\u00EF\u00BC\u00A1" byte[] bytes = phpUnicode.getBytes("ISO-8859-1"); 

создает массив байтов, содержащий столько байтов, что исходная строка имеет символы, а для каждого символа с индексом unicode ниже 256, то же числовое значение сохраняется в байтовом массиве.

Символ FULLWIDTH LATIN CAPITAL LETTER A (U + FF41) отсутствует в исходной строке, поэтому факт, что он не в ISO-8859-1, не имеет значения.

Я знаю, что ошибки перекодирования могут возникать при преобразовании символов в байты, поэтому я сказал, что ISO-8859-1 будет только «отображать каждый символ с размером unicode менее 256 байт с тем же значением»