2013-04-04 1 views
4

У меня есть экземпляр java.lang.CharSequence. Мне нужно определить, является ли этот экземпляр последовательностью Unicode scalar values (то есть, является ли экземпляр в форме кодирования UTF-16). Несмотря на заверения java.lang.String, строка Java не обязательно должна быть в форме кодировки UTF-16 (по крайней мере, не в соответствии с последним Unicode specification, в настоящее время 6.2), так как она может содержать изолированные surrogate code units. (Строка Java является, однако, Unicode 16-bit string.)Как проверить, является ли экземпляр CharSequence последовательностью скалярных значений Unicode?

Есть несколько очевидных путей, чтобы идти по этому поводу, в том числе:

  1. итерации по code points последовательностям, явно проверок каждому как Unicode скалярное значение.
  2. Используйте регулярное выражение для поиска изолированных суррогатных кодовых точек.
  3. Проведите последовательность символов через character-set encoder, что reports encoding errors.

Кажется, что-то вроде этого уже существует как библиотечная функция. Я просто не могу найти его в стандартном API. Я пропустил его, или мне нужно его реализовать?

+0

Существует а [isValidCodepoint] (http://docs.oracle.com/javase/7/docs/api/java/ lang/Character.html # isValidCodePoint% 28int% 29). Все, что нужно - это дополнительный фильтр для удаления суррогатов. –

+0

@ R.MartinhoFernandes Функция isValidCodePoint определяет, входит ли значение int в диапазон кодовых точек Unicode. Однако диапазон скалярных значений Unicode является ограничением на диапазон кодовых точек Unicode. –

+0

Ну, моя точка зрения в том, что isValidCodepoint - лучшее, что у вас есть. Я считаю, что вам придется получить эту проверку из внешней библиотеки (например, ICU) или сделать это самостоятельно. –

ответ

1

попробовать это Func

static boolean isValidUTF16(String s) { 
    for (int i = 0; i < s.length(); i++) { 
     if (Character.isLowSurrogate(s.charAt(i)) && (i == 0 || !Character.isHighSurrogate(s.charAt(i - 1))) 
       || Character.isHighSurrogate(s.charAt(i)) && (i == s.length() -1 || !Character.isLowSurrogate(s.charAt(i + 1)))) { 
      return false; 
     } 
    } 
    return true; 
} 

вот тест

public static void main(String args[]) { 
    System.out.println(isValidUTF16("\uDC00\uDBFF")); 
    System.out.println(isValidUTF16("\uDBFF\uDC00")); 
} 
+0

Это будет работать. Это можно сделать более эффективно, итерации над кодами, а не символами, но это фактически одна из возможных реализаций, перечисленных в вопросе. Я думаю, что у вас есть дополнительное условие в конце, хотя, поскольку 'i' никогда не может равняться' s.length() '. –

+0

спасибо за дополнительное условие, исправлено. Это было связано с рефакторингом и длинными строками в коде, не заметив его. –

 Смежные вопросы

  • Нет связанных вопросов^_^