Как заменить / удалить 4 (+) - байтовые символы из строки UTF-8 в Java? - PullRequest
18 голосов
/ 13 февраля 2012

Поскольку MySQL 5.1 не поддерживает 4-байтовые последовательности UTF-8, мне нужно заменить / удалить 4-байтовые последовательности в этих строках.

Я ищу чистый способ заменить этих персонажей.

Библиотеки Apache заменяют символы знаком вопроса, для этого случая вполне подойдет, хотя ASCII-эквивалент, конечно, будет лучше.

N.B. Входные данные поступают из внешних источников (имена электронной почты), и обновление базы данных не является решением на данный момент.

Ответы [ 3 ]

11 голосов
/ 16 мая 2013

Мы решили реализовать следующий метод в Java для этой проблемы. По сути, замена символов с более высокой кодовой точкой, чем последние 3-байтовые символы UTF-8.

Расчет смещения должен гарантировать, что мы остаемся в кодовых точках Юникода.

public static final String LAST_3_BYTE_UTF_CHAR = "\uFFFF";
public static final String REPLACEMENT_CHAR = "\uFFFD"; 

public static String toValid3ByteUTF8String(String s)  {
    final int length = s.length();
    StringBuilder b = new StringBuilder(length);
    for (int offset = 0; offset < length; ) {
       final int codepoint = s.codePointAt(offset);

       // do something with the codepoint
       if (codepoint > CharUtils.LAST_3_BYTE_UTF_CHAR.codePointAt(0)) {
           b.append(CharUtils.REPLACEMENT_CHAR);
       } else {
           if (Character.isValidCodePoint(codepoint)) {
               b.appendCodePoint(codepoint);
           } else {
               b.append(CharUtils.REPLACEMENT_CHAR);
           }
       }
       offset += Character.charCount(codepoint);
    }
    return b.toString();
}
9 голосов
/ 01 августа 2014

Другое простое решение - использовать регулярное выражение [^\u0000-\uFFFF]. Например в Java:

text.replaceAll("[^\\u0000-\\uFFFF]", "\uFFFD");
2 голосов
/ 13 февраля 2012

5-байтовые последовательности utf-8 начинаются с 111110xx-байта, а 6-байтовые последовательности utf-8 начинаются с 1111110x-байта.Важно отметить, что никакие последующие байты последовательностей utf-8 длиной 1-4 байта не содержат таких больших байтов, поскольку последующие байты всегда имеют форму 10xxxxxx.

Следовательно, вы можете просто пройти через байты, и каждый раз, когда вы видите байт типа 111110xx, выдается только '?'к выходному потоку / массиву, пропуская следующие 4 байта от входа;аналог для 6-байтовых последовательностей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...