Мені потрібно з’ясувати, чи є символ у рядку емодзі.
Наприклад, у мене такий персонаж:
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 сканерів Unicode:
Інший приклад, гліф 👌🏿 складається з 2 сканарів Unicode:
Останній, гліф 1️⃣, містить три символи Unicode:
Отже, при отрисуванні символів отримані гліфи дійсно мають значення.
Swift 5.0 і вище робить цей процес набагато простішим і позбавляє від деяких здогадок, які нам потрібно було зробити. Unicode.Scalar
Новий Property
тип допомагає визначити, з чим ми маємо справу. Однак ці властивості мають сенс лише при перевірці інших скалярів у гліфі. Ось чому ми додамо кілька зручних методів до класу символів, щоб допомогти нам.
Більш детально я написав статтю, в якій пояснював, як це працює .
Для 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 на всі модифікатори, але це набагато простіше в обробці. І оскільки Свіфт зараз зараховує Emoji з модифікаторами (наприклад: 👨👩👧👦, 👨🏻💻, 🏴) як 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 вказує на цікавий спосіб отримати всі емодзі:
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 ви тепер можете перевіряти властивості unicode кожного символу у вашому рядку. Це дає нам зручну isEmoji
змінну для кожної літери. Проблема полягає у isEmoji
поверненні істини для будь-якого символу, який можна перетворити на 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
Свіфт 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
Свіфт 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 юнікодських скалярів хороша для одного персонажа. І недостатньо гнучкий для струн.
Натомість ми можемо використовувати регулярні вирази - більш універсальний підхід. Нижче наведено детальний опис того, як це працює. І тут іде рішення.
У 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
}
}
Окремі Emoji (гліфи) можуть бути відтворені за допомогою різних символів, послідовностей та їх комбінацій. Специфікація Unicode визначає кілька можливих подань символів Emoji.
Персонаж Emoji, відтворений одним скаляром Unicode.
Unicode визначає символ Emoji як:
emoji_character := \p{Emoji}
Але це не обов'язково означає, що такий персонаж буде намальований як смайлик. Звичайний числовий символ "1" має властивість Emoji бути істинним, хоча воно все ще може бути намальоване як текст. І є перелік таких символів: #, ©, 4 тощо.
Слід подумати, що ми можемо використовувати додаткове властивість для перевірки: “Emoji_Presentation”. Але це не працює так. Є такі смайли, як 🏟 або 🛍, які мають властивість Emoji_Presentation = false.
Щоб переконатися, що символ за замовчуванням намальований як Emoji, ми повинні перевірити його категорію: це має бути «Інший_символ».
Отже, насправді регулярний вираз для односимвольних смайлів слід визначати як:
emoji_character := \p{Emoji}&&\p{Other_symbol}
Символ, який зазвичай можна намалювати як текст або як Emoji. Зовнішній вигляд залежить від спеціального наступного символу, селектора презентації, який вказує тип його презентації. \ x {FE0E} визначає подання тексту. \ x {FE0F} визначає подання смайликів.
Список таких символів можна знайти [тут] ( https://unicode.org/Public/emoji/12.1/emoji-variation-sequences.txt ).
Юнікод визначає послідовність презентацій таким чином:
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".
Unicode визначає їх як:
emoji_flag_sequence := regional_indicator regional_indicator
Наприклад, прапор України 🇺🇦 насправді представлений двома скалярами: \ u {0001F1FA \ u {0001F1E6}
Регулярний вираз для нього:
emoji_flag_sequence := \p{RI}{2}
Послідовність, яка використовує так звану базу_тегів, за якою слідує спеціальна специфікація тегу, складена з діапазону символів \ x {E0020} - \ x {E007E} і завершена позначкою tag_end \ x {E007F}.
Unicode визначає це так:
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.
У списку Emoji Unicode 12.1 існує лише три таких Emoji . Всі вони є прапорами країн Великобританії: Англії 🏴, Шотландії 🏴 та Уельсу 🏴. І всі вони засновані на одному персонажі Emoji. Отже, нам краще перевірити лише таку послідовність.
Регулярний вираз:
\p{Emoji} [\x{E0020}-\x{E007E}]+ \x{E007F}
Столяр нульової ширини - це скаляр \ x {200D}. За його допомогою кілька персонажів, які вже самі по собі є емоджами, можна об’єднати в нових.
Наприклад, "сім'я з батьком, сином та дочкою" Emoji 👨👧👦 відтворюється поєднанням батька 👨, дочки 👧 та сина 👦 Emojis, склеєних символами ZWJ.
Дозволено склеювати елементи, які є одиничними символами Emoji, послідовностями презентації та модифікатора.
Регулярний вираз для такої послідовності загалом виглядає так:
emoji_zwj_sequence := emoji_zwj_element (\x{200d} emoji_zwj_element )+
Всі згадані вище подання Emoji можна описати одним регулярним виразом:
\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}]
)
)*
у мене була та ж проблема, і я закінчив робити a String
та Character
розширення.
Код занадто довгий для публікації, оскільки в ньому фактично перераховані всі смайли (із офіційного списку Unicode v5.0), а CharacterSet
ви можете знайти його тут:
https://github.com/piterwilson/StringEmoji
Набір символів, що містить усі відомі смайли (як описано в офіційному списку Unicode 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 міститьEmoji: Bool {get}
Чи String
містить екземпляр відомий символ Emoji чи ні
print("".containsEmoji) // false
print("😁".containsEmoji) // true
print("😁😜".containsEmoji) // true
var unicodeName: Рядок {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: Рядок {get}
Повертає результат a 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