Как сравнить каждый символ строки при учете символов длиной> 1?

У меня есть переменная строка, которая может содержать любой символ юникода. Одним из этих символов Юникода является han 𩸽.

Дело в том, что этот символ "han" имеет "𩸽".length() == 2, но записывается в строку как один символ.

Учитывая приведенный ниже код, как бы я перебирал все символы и сравнивал каждый из них, учитывая тот факт, что он может содержать один символ с длиной больше 1?

for ( int i = 0; i < string.length(); i++ ) {
    char character = string.charAt( i );
    if ( character == '𩸽' ) {
        // Fail, it interprets as 2 chars =/
    }
}

EDIT:
Этот вопрос не дублируется. Это спрашивает, как итерации для каждого символа String при рассмотрении символов, содержащих .length() > 1 (символ не как тип char, а как представление написанного символа). Этот вопрос не требует предварительного знания того, как итерации по кодовым точкам Unicode строки Java, хотя ответ, упоминающий, также может быть правильным.

Ответы

Ответ 1

int hanCodePoint = "𩸽".codePointAt(0);
for (int i = 0; i < string.length();) {
    int currentCodePoint = string.codePointAt(i);
    if (currentCodePoint == hanCodePoint) {
        // do something here.
    }
    i += Character.charCount(currentCodePoint);
}

Ответ 2

Методы String.charAt и String.length обрабатывают String как последовательность кодовых единиц UTF-16. Вы хотите обрабатывать строку как кодовые точки Unicode.

Посмотрите на методы "кодовой точки" в API String:

  • codePointAt(int index) возвращает (32-разрядную) кодовую точку при заданном индексе кодовой единицы
  • offsetByCodePoints(int index, int codePointOffset) возвращает индекс кода, соответствующий codePointOffset кодам от кодового блока в index.
  • codePointCount(int beginIndex, int endIndex) подсчитывает кодовые точки между двумя индексами кода.

Индексирование строки индексом кодовой точки немного сложно, особенно если строка длинна, и вы хотите сделать это эффективно. Тем не менее, это эффективный, хотя код довольно громоздкий.

@sstan ответ - это одно из решений.

Ответ 3

Это будет проще, если вы будете обрабатывать как строку, так и данные, которые вы ищете, как String s. Если вам просто нужно проверить наличие этого символа:

if (string.contains("𩸽") {
    // do something here.
}

Если вам нужен индекс, в котором отображается этот символ:

int i = string.indexOf("𩸽");
if (i >= 0) {
    // do something with i here.
}

И если вам действительно нужно перебирать каждую кодовую точку, см. Как выполнить итерацию по кодовым точкам Unicode строки Java?.

Ответ 4

Символ ASCII занимает половину суммы, которую делает Unicode char, поэтому логично, что символ han имеет длину 2. Это не ASCII char, а не буква Unicode. Если бы это был второй случай, письмо будет отображаться правильно.