Мне нужно выяснить, является ли символ в строке смайликом.
Например, у меня есть такой персонаж:
let string = "😀"
let character = Array(string)[0]
Мне нужно выяснить, является ли этот персонаж смайликом.
Мне нужно выяснить, является ли символ в строке смайликом.
Например, у меня есть такой персонаж:
let string = "😀"
let character = Array(string)[0]
Мне нужно выяснить, является ли этот персонаж смайликом.
let character = string[string.index(after: string.startIndex)]
или let secondCharacter = string[string.index(string.startIndex, offsetBy: 1)]
Ответы:
Я наткнулся на разницу между символами, скалярами Unicode и глифами.
Например, глиф 👨👨👧👧 состоит из 7 скаляров юникода:
Другой пример, глиф 👌🏿 состоит из двух скаляров юникода:
Последний, глиф 1️⃣, содержит три символа Юникода:
Поэтому при рендеринге символов действительно имеют значение полученные глифы.
Swift 5.0 и выше значительно упрощает этот процесс и избавляет от некоторых догадок, которые нам нужно было делать. Unicode.Scalar
Новый Property
тип помогает определить, с чем мы имеем дело. Однако эти свойства имеют смысл только при проверке других скаляров внутри глифа. Вот почему мы добавим несколько удобных методов в класс Character, чтобы помочь нам.
Для более подробной информации я написал статью, объясняющую, как это работает .
Для Swift 5.0 это оставляет вам следующий результат:
extension Character {
/// A simple emoji is one scalar and presented to the user as an Emoji
var isSimpleEmoji: Bool {
guard let firstScalar = unicodeScalars.first else { return false }
return firstScalar.properties.isEmoji && firstScalar.value > 0x238C
}
/// Checks if the scalars will be merged into an emoji
var isCombinedIntoEmoji: Bool { unicodeScalars.count > 1 && unicodeScalars.first?.properties.isEmoji ?? false }
var isEmoji: Bool { isSimpleEmoji || isCombinedIntoEmoji }
}
extension String {
var isSingleEmoji: Bool { count == 1 && containsEmoji }
var containsEmoji: Bool { contains { $0.isEmoji } }
var containsOnlyEmoji: Bool { !isEmpty && !contains { !$0.isEmoji } }
var emojiString: String { emojis.map { String($0) }.reduce("", +) }
var emojis: [Character] { filter { $0.isEmoji } }
var emojiScalars: [UnicodeScalar] { filter { $0.isEmoji }.flatMap { $0.unicodeScalars } }
}
Это даст вам следующие результаты:
"A̛͚̖".containsEmoji // false
"3".containsEmoji // false
"A̛͚̖▶️".unicodeScalars // [65, 795, 858, 790, 9654, 65039]
"A̛͚̖▶️".emojiScalars // [9654, 65039]
"3️⃣".isSingleEmoji // true
"3️⃣".emojiScalars // [51, 65039, 8419]
"👌🏿".isSingleEmoji // true
"🙎🏼♂️".isSingleEmoji // true
"🇹🇩".isSingleEmoji // true
"⏰".isSingleEmoji // true
"🌶".isSingleEmoji // true
"👨👩👧👧".isSingleEmoji // true
"🏴".isSingleEmoji // true
"🏴".containsOnlyEmoji // true
"👨👩👧👧".containsOnlyEmoji // true
"Hello 👨👩👧👧".containsOnlyEmoji // false
"Hello 👨👩👧👧".containsEmoji // true
"👫 Héllo 👨👩👧👧".emojiString // "👫👨👩👧👧"
"👨👩👧👧".count // 1
"👫 Héllœ 👨👩👧👧".emojiScalars // [128107, 128104, 8205, 128105, 8205, 128103, 8205, 128103]
"👫 Héllœ 👨👩👧👧".emojis // ["👫", "👨👩👧👧"]
"👫 Héllœ 👨👩👧👧".emojis.count // 2
"👫👨👩👧👧👨👨👦".isSingleEmoji // false
"👫👨👩👧👧👨👨👦".containsOnlyEmoji // true
Для более старых версий Swift ознакомьтесь с этой сутью, содержащей мой старый код.
containsOnlyEmoji
проверки. Я также обновил пример до Swift 3.0.
Самый простой, чистый и быстрый способ добиться этого - просто проверить кодовые точки Unicode для каждого символа в строке на известные диапазоны эмодзи и дингбатов, например:
extension String {
var containsEmoji: Bool {
for scalar in unicodeScalars {
switch scalar.value {
case 0x1F600...0x1F64F, // Emoticons
0x1F300...0x1F5FF, // Misc Symbols and Pictographs
0x1F680...0x1F6FF, // Transport and Map
0x2600...0x26FF, // Misc symbols
0x2700...0x27BF, // Dingbats
0xFE00...0xFE0F, // Variation Selectors
0x1F900...0x1F9FF, // Supplemental Symbols and Pictographs
0x1F1E6...0x1F1FF: // Flags
return true
default:
continue
}
}
return false
}
}
0x1F900...0x1F9FF
(согласно Википедии). Не уверен, что смайликами следует считать весь диапазон.
extension String {
func containsEmoji() -> Bool {
for scalar in unicodeScalars {
switch scalar.value {
case 0x3030, 0x00AE, 0x00A9,// Special Characters
0x1D000...0x1F77F, // Emoticons
0x2100...0x27BF, // Misc symbols and Dingbats
0xFE00...0xFE0F, // Variation Selectors
0x1F900...0x1F9FF: // Supplemental Symbols and Pictographs
return true
default:
continue
}
}
return false
}
}
Это мое исправление с обновленными диапазонами.
… Представил новый способ проверки именно этого!
Вы должны сломать ваш String
в его Scalars
. У каждого Scalar
есть Property
значение, которое поддерживает это isEmoji
значение!
На самом деле вы даже можете проверить, является ли Scalar модификатором Emoji или более. Ознакомьтесь с документацией Apple: https://developer.apple.com/documentation/swift/unicode/scalar/properties.
Вы можете рассмотреть возможность проверки isEmojiPresentation
вместо isEmoji
, потому что Apple заявляет следующее для isEmoji
:
Это свойство верно для скаляров, которые по умолчанию визуализируются как эмодзи, а также для скаляров, которые имеют нестандартный рендеринг эмодзи, за которым следует U + FE0F VARIATION SELECTOR-16. Сюда входят некоторые скаляры, которые обычно не считаются смайликами.
Таким образом, Emoji разбивается на все модификаторы, но с ним намного проще справиться. И поскольку Swift теперь считает эмодзи с модификаторами (например: 👨👩👧👦, 👨🏻💻, 🏴) как 1, вы можете делать все, что угодно.
var string = "🤓 test"
for scalar in string.unicodeScalars {
let isEmoji = scalar.properties.isEmoji
print("\(scalar.description) \(isEmoji)"))
}
// 🤓 true
// false
// t false
// e false
// s false
// t false
NSHipster указывает на интересный способ получить все Emoji:
import Foundation
var emoji = CharacterSet()
for codePoint in 0x0000...0x1F0000 {
guard let scalarValue = Unicode.Scalar(codePoint) else {
continue
}
// Implemented in Swift 5 (SE-0221)
// https://github.com/apple/swift-evolution/blob/master/proposals/0221-character-properties.md
if scalarValue.properties.isEmoji {
emoji.insert(scalarValue)
}
}
scalar.properties.isEmoji scalar.properties.isEmojiPresentation scalar.properties.isEmojiModifier scalar.properties.isEmojiModifierBase scalar.properties.isJoinControl scalar.properties.isVariationSelector
"6".unicodeScalars.first!.properties.isEmoji
, true
В Swift 5 теперь вы можете проверять свойства юникода каждого символа в вашей строке. Это дает нам удобную isEmoji
переменную для каждой буквы. Проблема в том, isEmoji
что вернет true для любого символа, который может быть преобразован в 2-байтовый смайлик, например 0-9.
Мы можем посмотреть на переменную, isEmoji
а также проверить наличие модификатора эмодзи, чтобы определить, будут ли неоднозначные символы отображаться как эмодзи.
Это решение должно быть гораздо более перспективным, чем предлагаемые здесь решения с регулярными выражениями.
extension String {
func containsOnlyEmojis() -> Bool {
if count == 0 {
return false
}
for character in self {
if !character.isEmoji {
return false
}
}
return true
}
func containsEmoji() -> Bool {
for character in self {
if character.isEmoji {
return true
}
}
return false
}
}
extension Character {
// An emoji can either be a 2 byte unicode character or a normal UTF8 character with an emoji modifier
// appended as is the case with 3️⃣. 0x238C is the first instance of UTF16 emoji that requires no modifier.
// `isEmoji` will evaluate to true for any character that can be turned into an emoji by adding a modifier
// such as the digit "3". To avoid this we confirm that any character below 0x238C has an emoji modifier attached
var isEmoji: Bool {
guard let scalar = unicodeScalars.first else { return false }
return scalar.properties.isEmoji && (scalar.value > 0x238C || unicodeScalars.count > 1)
}
}
Давая нам
"hey".containsEmoji() //false
"Hello World 😎".containsEmoji() //true
"Hello World 😎".containsOnlyEmojis() //false
"3".containsEmoji() //false
"3️⃣".containsEmoji() //true
Character("3️⃣").isEmoji // true
покаCharacter("3").isEmoji // false
Swift 3 Примечание:
Похоже, cnui_containsEmojiCharacters
метод был удален или перемещен в другую динамическую библиотеку. _containsEmoji
все равно должно работать.
let str: NSString = "hello😊"
@objc protocol NSStringPrivate {
func _containsEmoji() -> ObjCBool
}
let strPrivate = unsafeBitCast(str, to: NSStringPrivate.self)
strPrivate._containsEmoji() // true
str.value(forKey: "_containsEmoji") // 1
let swiftStr = "hello😊"
(swiftStr as AnyObject).value(forKey: "_containsEmoji") // 1
Swift 2.x:
Недавно я обнаружил частный API, в NSString
котором доступны функции для определения наличия в строке символа Emoji:
let str: NSString = "hello😊"
С протоколом objc и unsafeBitCast
:
@objc protocol NSStringPrivate {
func cnui_containsEmojiCharacters() -> ObjCBool
func _containsEmoji() -> ObjCBool
}
let strPrivate = unsafeBitCast(str, NSStringPrivate.self)
strPrivate.cnui_containsEmojiCharacters() // true
strPrivate._containsEmoji() // true
С valueForKey
:
str.valueForKey("cnui_containsEmojiCharacters") // 1
str.valueForKey("_containsEmoji") // 1
С чистой строкой Swift вы должны преобразовать строку, как AnyObject
перед использованием valueForKey
:
let str = "hello😊"
(str as AnyObject).valueForKey("cnui_containsEmojiCharacters") // 1
(str as AnyObject).valueForKey("_containsEmoji") // 1
Методы, найденные в файле заголовка NSString .
Вы можете использовать этот пример кода или этот модуль .
Чтобы использовать его в Swift, импортируйте категорию в YourProject_Bridging_Header
#import "NSString+EMOEmoji.h"
Затем вы можете проверить диапазон для каждого смайлика в своей строке:
let example: NSString = "string👨👨👧👧with😍emojis✊🏿" //string with emojis
let containsEmoji: Bool = example.emo_containsEmoji()
print(containsEmoji)
// Output: ["true"]
На протяжении многих лет эти решения для обнаружения смайликов продолжают ломаться, поскольку Apple добавляет новые смайлы с новыми методами (например, смайлики с оттенком кожи, созданные путем предварительного проклятия персонажа дополнительным персонажем) и т. Д.
В конце концов я сломался и просто написал следующий метод, который работает для всех текущих смайлов и должен работать для всех будущих смайлов.
Решение создает UILabel с символом и черным фоном. Затем CG делает снимок этикетки, и я просматриваю все пиксели снимка на предмет любых не сплошных черных пикселей. Причина, по которой я добавляю черный фон, - избежать проблем с ложной окраской из-за субпиксельного рендеринга.
Решение работает ОЧЕНЬ быстро на моем устройстве, я могу проверять сотни символов в секунду, но следует отметить, что это решение CoreGraphics и не должно интенсивно использоваться, как вы могли бы с обычным текстовым методом. Обработка графики требует больших объемов данных, поэтому одновременная проверка тысяч символов может привести к заметным задержкам.
-(BOOL)isEmoji:(NSString *)character {
UILabel *characterRender = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
characterRender.text = character;
characterRender.font = [UIFont fontWithName:@"AppleColorEmoji" size:12.0f];//Note: Size 12 font is likely not crucial for this and the detector will probably still work at an even smaller font size, so if you needed to speed this checker up for serious performance you may test lowering this to a font size like 6.0
characterRender.backgroundColor = [UIColor blackColor];//needed to remove subpixel rendering colors
[characterRender sizeToFit];
CGRect rect = [characterRender bounds];
UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
CGContextRef contextSnap = UIGraphicsGetCurrentContext();
[characterRender.layer renderInContext:contextSnap];
UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef imageRef = [capturedImage CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;//Note: Alpha Channel not really needed, if you need to speed this up for serious performance you can refactor this pixel scanner to just RGB
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
BOOL colorPixelFound = NO;
int x = 0;
int y = 0;
while (y < height && !colorPixelFound) {
while (x < width && !colorPixelFound) {
NSUInteger byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
CGFloat red = (CGFloat)rawData[byteIndex];
CGFloat green = (CGFloat)rawData[byteIndex+1];
CGFloat blue = (CGFloat)rawData[byteIndex+2];
CGFloat h, s, b, a;
UIColor *c = [UIColor colorWithRed:red green:green blue:blue alpha:1.0f];
[c getHue:&h saturation:&s brightness:&b alpha:&a];//Note: I wrote this method years ago, can't remember why I check HSB instead of just checking r,g,b==0; Upon further review this step might not be needed, but I haven't tested to confirm yet.
b /= 255.0f;
if (b > 0) {
colorPixelFound = YES;
}
x++;
}
x=0;
y++;
}
return colorPixelFound;
}
AppleColorEmoji
, добавив это в качестве отказоустойчивого, хотя я думаю, что Apple в любом случае будет использовать его по умолчанию для них
Для Swift 3.0.2 самый простой ответ:
class func stringContainsEmoji (string : NSString) -> Bool
{
var returnValue: Bool = false
string.enumerateSubstrings(in: NSMakeRange(0, (string as NSString).length), options: NSString.EnumerationOptions.byComposedCharacterSequences) { (substring, substringRange, enclosingRange, stop) -> () in
let objCString:NSString = NSString(string:substring!)
let hs: unichar = objCString.character(at: 0)
if 0xd800 <= hs && hs <= 0xdbff
{
if objCString.length > 1
{
let ls: unichar = objCString.character(at: 1)
let step1: Int = Int((hs - 0xd800) * 0x400)
let step2: Int = Int(ls - 0xdc00)
let uc: Int = Int(step1 + step2 + 0x10000)
if 0x1d000 <= uc && uc <= 0x1f77f
{
returnValue = true
}
}
}
else if objCString.length > 1
{
let ls: unichar = objCString.character(at: 1)
if ls == 0x20e3
{
returnValue = true
}
}
else
{
if 0x2100 <= hs && hs <= 0x27ff
{
returnValue = true
}
else if 0x2b05 <= hs && hs <= 0x2b07
{
returnValue = true
}
else if 0x2934 <= hs && hs <= 0x2935
{
returnValue = true
}
else if 0x3297 <= hs && hs <= 0x3299
{
returnValue = true
}
else if hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50
{
returnValue = true
}
}
}
return returnValue;
}
Абсолютно аналогичный ответ на те, что писали до меня, но с обновленным набором скаляров эмодзи.
extension String {
func isContainEmoji() -> Bool {
let isContain = unicodeScalars.first(where: { $0.isEmoji }) != nil
return isContain
}
}
extension UnicodeScalar {
var isEmoji: Bool {
switch value {
case 0x1F600...0x1F64F,
0x1F300...0x1F5FF,
0x1F680...0x1F6FF,
0x1F1E6...0x1F1FF,
0x2600...0x26FF,
0x2700...0x27BF,
0xFE00...0xFE0F,
0x1F900...0x1F9FF,
65024...65039,
8400...8447,
9100...9300,
127000...127600:
return true
default:
return false
}
}
}
Вы можете использовать NSString-RemoveEmoji следующим образом:
if string.isIncludingEmoji {
}
Для указанной задачи есть хорошее решение . Но проверка Unicode.Scalar.Properties скаляров Unicode хороша для одного символа. И недостаточно гибок для струнных.
Вместо этого мы можем использовать регулярные выражения - более универсальный подход. Ниже приводится подробное описание того, как это работает. И вот решение.
В Swift вы можете проверить, является ли String одним символом Emoji, используя расширение с таким вычисляемым свойством:
extension String {
var isSingleEmoji : Bool {
if self.count == 1 {
let emodjiGlyphPattern = "\\p{RI}{2}|(\\p{Emoji}(\\p{EMod}|\\x{FE0F}\\x{20E3}?|[\\x{E0020}-\\x{E007E}]+\\x{E007F})|[\\p{Emoji}&&\\p{Other_symbol}])(\\x{200D}(\\p{Emoji}(\\p{EMod}|\\x{FE0F}\\x{20E3}?|[\\x{E0020}-\\x{E007E}]+\\x{E007F})|[\\p{Emoji}&&\\p{Other_symbol}]))*"
let fullRange = NSRange(location: 0, length: self.utf16.count)
if let regex = try? NSRegularExpression(pattern: emodjiGlyphPattern, options: .caseInsensitive) {
let regMatches = regex.matches(in: self, options: NSRegularExpression.MatchingOptions(), range: fullRange)
if regMatches.count > 0 {
// if any range found — it means, that that single character is emoji
return true
}
}
}
return false
}
}
Один эмодзи (глиф) может быть воспроизведен с помощью ряда различных символов, последовательностей и их комбинаций. Спецификация Unicode определяет несколько возможных представлений символов Emoji.
Символ Emoji, воспроизводимый одним скаляром Unicode.
Unicode определяет символ Emoji как:
emoji_character := \p{Emoji}
Но это не обязательно означает, что такой персонаж будет нарисован как эмодзи. Обычный числовой символ «1» имеет свойство Emoji, равное истине, хотя он все равно может отображаться как текст. И есть список таких символов: #, ©, 4 и т. Д.
Надо думать, что для проверки можно использовать дополнительное свойство: «Emoji_Presentation». Но так не работает. Есть эмодзи, например 🏟 или 🛍, у которых свойство Emoji_Presentation = false.
Чтобы убедиться, что персонаж по умолчанию отрисовывается как Emoji, мы должны проверить его категорию: это должно быть «Other_symbol».
Итак, на самом деле регулярное выражение для односимвольных эмодзи следует определять как:
emoji_character := \p{Emoji}&&\p{Other_symbol}
Персонаж, который обычно можно рисовать как текст или как эмодзи. Его внешний вид зависит от специального следующего символа, селектора представления, который указывает его тип представления. \ x {FE0E} определяет текстовое представление. \ x {FE0F} определяет представление эмодзи.
Список таких символов можно найти [здесь] ( https://unicode.org/Public/emoji/12.1/emoji-variation-sequences.txt ).
Unicode определяет последовательность представления следующим образом:
emoji_presentation_sequence := emoji_character emoji_presentation_selector
Последовательность регулярных выражений для него:
emoji_presentation_sequence := \p{Emoji} \x{FE0F}
Последовательность очень похожа на последовательность представления, но в конце есть дополнительный скаляр: \ x {20E3}. Набор возможных базовых скаляров, используемых для этого, довольно узок: 0-9 # * - и все. Примеры: 1️⃣, 8️⃣, * ️⃣.
Unicode определяет последовательность клавиш следующим образом:
emoji_keycap_sequence := [0-9#*] \x{FE0F 20E3}
Регулярное выражение для него:
emoji_keycap_sequence := \p{Emoji} \x{FE0F} \x{FE0F}
Некоторые эмодзи могут иметь измененный вид, например оттенок кожи. Например Emoji 🧑 может быть другим: 🧑🧑🏻🧑🏼🧑🏽🧑🏾🧑🏿. Чтобы определить Emoji, который в данном случае называется «Emoji_Modifier_Base», можно использовать последующий «Emoji_Modifier».
В целом такая последовательность выглядит так:
emoji_modifier_sequence := emoji_modifier_base emoji_modifier
Чтобы обнаружить это, мы можем искать последовательность регулярных выражений:
emoji_modifier_sequence := \p{Emoji} \p{EMod}
Флаги - это эмодзи с их особой структурой. Каждый флаг представлен двумя символами «Regional_Indicator».
Юникод определяет их как:
emoji_flag_sequence := regional_indicator regional_indicator
Например флаг Украины 🇺🇦 по сути представлен двумя скалярами: \ u {0001F1FA \ u {0001F1E6}
Регулярное выражение для него:
emoji_flag_sequence := \p{RI}{2}
Последовательность, которая использует так называемую tag_base, за которой следует спецификация настраиваемого тега, состоящая из диапазона символов \ x {E0020} - \ x {E007E} и завершенная меткой tag_end \ x {E007F}.
Юникод определяет это так:
emoji_tag_sequence := tag_base tag_spec tag_end
tag_base := emoji_character
| emoji_modifier_sequence
| emoji_presentation_sequence
tag_spec := [\x{E0020}-\x{E007E}]+
tag_end := \x{E007F}
Странно то, что Unicode позволяет тегу быть основанным на emoji_modifier_sequence или emoji_presentation_sequence в ED-14a . Но в то же время в регулярных выражениях, представленных в той же документации, они, похоже, проверяют последовательность только на основе одного символа Emoji.
В списке эмодзи Unicode 12.1 определены только три таких эмодзи . Все они являются флагами стран Великобритании: Англии 🏴, Шотландии 🏴 и Уэльса 🏴. И все они основаны на одном персонаже Emoji. Так что лучше проверять только такую последовательность.
Регулярное выражение:
\p{Emoji} [\x{E0020}-\x{E007E}]+ \x{E007F}
Соединитель нулевой ширины - это скаляр \ x {200D}. С его помощью несколько персонажей, которые сами по себе уже являются Emojis, могут быть объединены в новых.
Например, смайлик «семья с отцом, сыном и дочерью» 👨👧👦 воспроизводится комбинацией смайликов отца 👨, дочери 👧 и сына, склеенных с символами ZWJ.
Разрешено склеивать элементы, которыми являются одиночные символы эмодзи, последовательности презентаций и модификаторов.
Регулярное выражение для такой последовательности в целом выглядит так:
emoji_zwj_sequence := emoji_zwj_element (\x{200d} emoji_zwj_element )+
Все упомянутые выше представления эмодзи можно описать одним регулярным выражением:
\p{RI}{2}
| ( \p{Emoji}
( \p{EMod}
| \x{FE0F}\x{20E3}?
| [\x{E0020}-\x{E007E}]+\x{E007F}
)
|
[\p{Emoji}&&\p{Other_symbol}]
)
( \x{200D}
( \p{Emoji}
( \p{EMod}
| \x{FE0F}\x{20E3}?
| [\x{E0020}-\x{E007E}]+\x{E007F}
)
| [\p{Emoji}&&\p{Other_symbol}]
)
)*
я была такая же проблема и в конечном итоге делает String
и Character
расширения.
Код слишком длинный для публикации, так как на самом деле в нем перечислены все смайлы (из официального списка Unicode v5.0), CharacterSet
вы можете найти его здесь:
https://github.com/piterwilson/StringEmoji
Набор символов, содержащий все известные смайлы (как описано в официальном Unicode List 5.0 http://unicode.org/emoji/charts-5.0/emoji-list.html )
Независимо от того, String
представляет ли экземпляр известного одиночного символа Emoji
print("".isEmoji) // false
print("😁".isEmoji) // true
print("😁😜".isEmoji) // false (String is not a single Emoji)
var containsEmoji: Bool {get}
String
Содержит ли экземпляр известного персонажа Emoji
print("".containsEmoji) // false
print("😁".containsEmoji) // true
print("😁😜".containsEmoji) // true
var unicodeName: String {get}
Применяет kCFStringTransformToUnicodeName
- CFStringTransform
к копии строки
print("á".unicodeName) // \N{LATIN SMALL LETTER A WITH ACUTE}
print("😜".unicodeName) // "\N{FACE WITH STUCK-OUT TONGUE AND WINKING EYE}"
var niceUnicodeName: String {get}
Возвращает результат kCFStringTransformToUnicodeName
- CFStringTransform
с удаленными \N{
префиксами и }
суффиксами
print("á".unicodeName) // LATIN SMALL LETTER A WITH ACUTE
print("😜".unicodeName) // FACE WITH STUCK-OUT TONGUE AND WINKING EYE
Независимо от того, Character
представляет ли экземпляр известного персонажа Emoji
print("".isEmoji) // false
print("😁".isEmoji) // true