Обновление для Swift 4 (Xcode 9)
Начиная с Swift 4 (протестированного с бета-версией Xcode 9) кластеры графем прерываются после каждого второго символа регионального индикатора, как это предусмотрено стандартом Unicode 9:
let str1 = "????????????????????????????????????????"
print(str1.count) // 5
print(Array(str1)) // ["????????", "????????", "????????", "????????", "????????"]
Также String
- это набор его символов (опять же), поэтому можно получить количество символов с помощью str1.count
.
(Старый ответ для Swift 3 и старше :)
Из «Границы трех кластеров графем» в «Стандартном приложении № 29 СЕГМЕНТАЦИЯ ТЕКСТА UNICODE. ": (курсив добавлен):
Унаследованный кластер графем определяется как основа (например, A или カ), за которой следует ноль или более продолжающихся символов. Один из способов представить это как последовательность символов, образующих «стек».
Основой могут быть отдельные символы или любая последовательность символов хангыль-джамо, образующая слог хангыль, как определено в D133 в стандарте Unicode, или любая последовательность символов Regional_Indicator (RI). Символы RI используются парами для обозначения символов национального флага Emoji, соответствующих кодам стран ISO. Последовательности из более чем двух символов RI должны быть разделены другими символами, например U + 200B ZWSP.
(Спасибо @rintaro за ссылку).
Быстрый символ представляет собой расширенный кластер графем, поэтому (согласно этой ссылке) правильно, что любая последовательность региональных индикаторных символов считается одним символом.
Вы можете разделить «флаги» НУЛЕВОЙ ШИРИНОЙ, НЕ СОЕДИНЯЮЩЕЙ:
let str1 = "????????\u{200C}????????"
print(str1.characters.count) // 2
или вставьте ПРОБЕЛ НУЛЕВОЙ ШИРИНЫ:
let str2 = "????????\u{200B}????????"
print(str2.characters.count) // 3
Это также решает возможные неоднозначности, например должно быть «???? ???? ???? ????» быть «???? ???????? ????» или «???????? ????????»?
См. Также Как узнать, есть ли два смайлика будет отображаться как один смайлик? о возможном методе подсчета количества «составных символов» в строке Swift, который вернет 5
для вашего let str1 = "????????????????????????????????????????"
.
person
Martin R
schedule
11.11.2014
let str1 = "\u{1F1E6}\u{1F1E7}\u{1F1E8}\u{1F1E9}\u{1F1EA}\u{1F1EB}"
печатается как????????????????????????
, но считается как один символ. - person Martin R   schedule 11.11.2014str1.startIndex.successor() == str1.endIndex
- person rintaro   schedule 11.11.2014