Saya perlu mencari tahu apakah karakter dalam string adalah emoji.
Misalnya, saya memiliki karakter ini:
let string = "๐"
let character = Array(string)[0]
Saya perlu mencari tahu apakah karakter itu adalah emoji.
Saya perlu mencari tahu apakah karakter dalam string adalah emoji.
Misalnya, saya memiliki karakter ini:
let string = "๐"
let character = Array(string)[0]
Saya perlu mencari tahu apakah karakter itu adalah emoji.
let character = string[string.index(after: string.startIndex)]
atau let secondCharacter = string[string.index(string.startIndex, offsetBy: 1)]
Jawaban:
Apa yang saya temukan adalah perbedaan antara karakter, skalar unicode, dan mesin terbang.
Misalnya, mesin terbang ๐จโ๐จโ๐งโ๐ง terdiri dari 7 skalar unicode:
Contoh lain, mesin terbang ๐๐ฟ terdiri dari 2 skalar unicode:
Yang terakhir, mesin terbang 1๏ธโฃ berisi tiga karakter unicode:
Jadi saat merender karakter, mesin terbang yang dihasilkan sangat penting.
Swift 5.0 dan yang lebih baru membuat proses ini lebih mudah dan menghilangkan beberapa tebakan yang perlu kami lakukan. Unicode.Scalar
Ini baru Property
jenis membantu adalah menentukan apa yang kita berurusan sedang bersama. Namun, properti tersebut hanya masuk akal saat memeriksa skalar lain di dalam mesin terbang. Inilah mengapa kami akan menambahkan beberapa metode praktis ke kelas Karakter untuk membantu kami.
Untuk lebih detail, saya menulis artikel yang menjelaskan cara kerjanya .
Untuk Swift 5.0, hasilnya adalah sebagai berikut:
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 } }
}
Yang akan memberi Anda hasil sebagai berikut:
"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
Untuk versi Swift yang lebih lama, lihat inti yang berisi kode lama saya.
containsOnlyEmoji
pemeriksaan. Saya juga memperbarui contoh ke Swift 3.0.
Cara termudah, paling bersih, dan tercepat untuk melakukannya adalah dengan memeriksa poin kode Unicode untuk setiap karakter dalam string terhadap rentang emoji dan dingbat yang diketahui, seperti:
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
(per Wikipedia). Tidak yakin semua rentang harus dianggap emoji.
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
}
}
Ini adalah perbaikan saya, dengan rentang yang diperbarui.
โฆ Memperkenalkan cara baru untuk memeriksa ini!
Anda harus membobol Anda String
menjadi miliknya Scalars
. Masing-masing Scalar
memiliki Property
nilai yang mendukung isEmoji
nilai tersebut!
Sebenarnya Anda bahkan dapat memeriksa apakah Scalar adalah pengubah Emoji atau lebih. Lihat dokumentasi Apple: https://developer.apple.com/documentation/swift/unicode/scalar/properties
Anda mungkin ingin mempertimbangkan untuk memeriksa isEmojiPresentation
daripada isEmoji
, karena Apple menyatakan berikut ini untuk isEmoji
:
Properti ini berlaku untuk skalar yang dirender sebagai emoji secara default dan juga untuk skalar yang memiliki rendering emoji non-default jika diikuti oleh U + FE0F VARIATION SELECTOR-16. Ini termasuk beberapa skalar yang biasanya tidak dianggap sebagai emoji.
Cara ini sebenarnya membagi Emoji menjadi semua pengubah, tetapi cara ini lebih mudah untuk ditangani. Dan karena Swift sekarang menghitung Emoji dengan pengubah (misalnya: ๐จโ๐ฉโ๐งโ๐ฆ, ๐จ๐ปโ๐ป, ๐ด) sebagai 1, Anda dapat melakukan semua jenis hal.
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 menunjukkan cara menarik untuk mendapatkan semua 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
akan dievaluasi sebagaitrue
Dengan Swift 5, Anda sekarang dapat memeriksa properti unicode dari setiap karakter dalam string Anda. Ini memberi kita isEmoji
variabel yang nyaman di setiap huruf. Masalahnya adalah isEmoji
akan mengembalikan nilai true untuk karakter apa pun yang dapat diubah menjadi emoji 2-byte, seperti 0-9.
Kita dapat melihat variabel isEmoji
dan juga memeriksa keberadaan pengubah emoji untuk menentukan apakah karakter ambigu akan ditampilkan sebagai emoji.
Solusi ini harus menjadi bukti masa depan yang jauh lebih banyak daripada solusi regex yang ditawarkan di sini.
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)
}
}
Memberi kami
"hey".containsEmoji() //false
"Hello World ๐".containsEmoji() //true
"Hello World ๐".containsOnlyEmojis() //false
"3".containsEmoji() //false
"3๏ธโฃ".containsEmoji() //true
Character("3๏ธโฃ").isEmoji // true
sementaraCharacter("3").isEmoji // false
Swift 3 Catatan:
Tampaknya cnui_containsEmojiCharacters
metode tersebut telah dihapus atau dipindahkan ke pustaka dinamis yang berbeda. _containsEmoji
harus tetap berfungsi.
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:
Saya baru-baru ini menemukan API pribadi NSString
yang memperlihatkan fungsionalitas untuk mendeteksi jika sebuah string berisi karakter Emoji:
let str: NSString = "hello๐"
Dengan protokol objc dan unsafeBitCast
:
@objc protocol NSStringPrivate {
func cnui_containsEmojiCharacters() -> ObjCBool
func _containsEmoji() -> ObjCBool
}
let strPrivate = unsafeBitCast(str, NSStringPrivate.self)
strPrivate.cnui_containsEmojiCharacters() // true
strPrivate._containsEmoji() // true
Dengan valueForKey
:
str.valueForKey("cnui_containsEmojiCharacters") // 1
str.valueForKey("_containsEmoji") // 1
Dengan string Swift murni, Anda harus mentransmisikan string seperti AnyObject
sebelumnya menggunakan valueForKey
:
let str = "hello๐"
(str as AnyObject).valueForKey("cnui_containsEmojiCharacters") // 1
(str as AnyObject).valueForKey("_containsEmoji") // 1
Metode yang ditemukan di file header NSString .
Anda dapat menggunakan contoh kode ini atau pod ini .
Untuk menggunakannya di Swift, impor kategori ke dalam YourProject_Bridging_Header
#import "NSString+EMOEmoji.h"
Kemudian Anda dapat memeriksa kisaran untuk setiap emoji di String Anda:
let example: NSString = "string๐จโ๐จโ๐งโ๐งwith๐emojisโ๐ฟ" //string with emojis
let containsEmoji: Bool = example.emo_containsEmoji()
print(containsEmoji)
// Output: ["true"]
Selama bertahun-tahun, solusi pendeteksi emoji ini terus rusak saat Apple menambahkan emoji baru dengan metode baru (seperti emoji dengan warna kulit yang dibuat dengan mengutuk karakter dengan karakter tambahan), dll.
Saya akhirnya rusak dan baru saja menulis metode berikut yang berfungsi untuk semua emoji saat ini dan harus berfungsi untuk semua emoji di masa mendatang.
Solusinya menciptakan UILabel dengan karakter dan latar belakang hitam. CG kemudian mengambil snapshot dari label dan saya memindai semua piksel dalam snapshot untuk piksel non-solid-black. Alasan saya menambahkan latar belakang hitam adalah untuk menghindari masalah pewarnaan palsu karena Subpixel Rendering
Solusinya berjalan SANGAT cepat di perangkat saya, saya dapat memeriksa ratusan karakter per detik, tetapi perlu dicatat bahwa ini adalah solusi CoreGraphics dan tidak boleh digunakan secara berlebihan seperti yang Anda bisa dengan metode teks biasa. Pemrosesan grafik adalah data yang berat sehingga memeriksa ribuan karakter sekaligus dapat menyebabkan kelambatan yang nyata.
-(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
, menambahkan bahwa sekarang sebagai brankas yang gagal, meskipun saya pikir Apple akan default untuk itu
Untuk Swift 3.0.2, jawaban berikut adalah yang paling sederhana:
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;
}
Jawaban yang benar-benar mirip dengan yang saya tulis sebelumnya, tetapi dengan set skalar emoji yang diperbarui.
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
}
}
}
Anda dapat menggunakan NSString-RemoveEmoji seperti ini:
if string.isIncludingEmoji {
}
Ada solusi yang bagus untuk tugas yang disebutkan. Tapi Memeriksa Properti Unicode.Scalar.Properti skalar unicode bagus untuk satu Karakter. Dan tidak cukup fleksibel untuk Strings.
Sebagai gantinya, kita dapat menggunakan Ekspresi Reguler - pendekatan yang lebih universal. Ada penjelasan rinci tentang cara kerjanya di bawah ini. Dan inilah solusinya.
Di Swift Anda dapat memeriksa, apakah String adalah satu karakter Emoji, menggunakan ekstensi dengan properti yang dihitung:
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 tunggal (mesin terbang) dapat direproduksi dengan sejumlah simbol, urutan, dan kombinasinya yang berbeda. Spesifikasi Unicode mendefinisikan beberapa kemungkinan representasi karakter Emoji.
Karakter Emoji direproduksi oleh satu Unicode Scalar.
Unicode mendefinisikan Karakter Emoji sebagai:
emoji_character := \p{Emoji}
Tetapi itu tidak berarti bahwa karakter seperti itu akan digambar sebagai Emoji. Simbol numerik biasa "1" memiliki properti Emoji yang benar, meskipun masih dapat digambar sebagai teks. Dan ada daftar simbol seperti itu: #, ยฉ, 4, dll.
Orang harus berpikir, bahwa kita dapat menggunakan properti tambahan untuk memeriksa: "Emoji_Presentation". Tapi tidak berhasil seperti ini. Ada Emoji seperti ๐ atau ๐, yang memiliki properti Emoji_Presentation = false.
Untuk memastikan, bahwa karakter digambar sebagai Emoji secara default, kita harus memeriksa kategorinya: ini harus "Simbol_lain".
Jadi, sebenarnya ekspresi reguler untuk Emoji Karakter Tunggal harus didefinisikan sebagai:
emoji_character := \p{Emoji}&&\p{Other_symbol}
Karakter, yang biasanya dapat digambar sebagai teks atau Emoji. Penampilannya tergantung pada simbol khusus berikut, pemilih presentasi, yang menunjukkan jenis presentasinya. \ x {FE0E} mendefinisikan representasi teks. \ x {FE0F} mendefinisikan representasi emoji.
Daftar simbol tersebut dapat ditemukan [di sini] (โจ https://unicode.org/Public/emoji/12.1/emoji-variation-sequences.txt ).
Unicode mendefinisikan urutan presentasi seperti ini:
emoji_presentation_sequence := emoji_character emoji_presentation_selector
Urutan ekspresi reguler untuk itu:
emoji_presentation_sequence := \p{Emoji} \x{FE0F}
Urutannya terlihat sangat mirip dengan urutan Presentasi, tetapi memiliki skalar tambahan di akhir: \ x {20E3}. Cakupan skalar dasar yang mungkin digunakan untuk itu agak sempit: 0-9 # * - dan itu saja. Contoh: 1๏ธโฃ, 8๏ธโฃ, * ๏ธโฃ.
Unicode mendefinisikan urutan keycap seperti ini:
emoji_keycap_sequence := [0-9#*] \x{FE0F 20E3}
Ekspresi reguler untuk itu:
emoji_keycap_sequence := \p{Emoji} \x{FE0F} \x{FE0F}
Beberapa Emoji dapat mengubah tampilan seperti warna kulit. Misalnya Emoji ๐ง bisa berbeda: ๐ง๐ง๐ป๐ง๐ผ๐ง๐ฝ๐ง๐พ๐ง๐ฟ. Untuk mendefinisikan Emoji, yang dalam hal ini disebut "Emoji_Modifier_Base", seseorang dapat menggunakan "Emoji_Modifier" berikutnya.
Secara umum urutan seperti ini terlihat seperti ini:
emoji_modifier_sequence := emoji_modifier_base emoji_modifier
Untuk mendeteksinya kita bisa mencari regular expression sequence:
emoji_modifier_sequence := \p{Emoji} \p{EMod}
Bendera adalah Emoji dengan strukturnya yang khas. Setiap bendera diwakili dengan dua simbol "Regional_Indicator".
Unicode mendefinisikannya seperti:
emoji_flag_sequence := regional_indicator regional_indicator
Misalnya bendera Ukraina ๐บ๐ฆ sebenarnya diwakili dengan dua skalar: \ u {0001F1FA \ u {0001F1E6}
Ekspresi reguler untuk itu:
emoji_flag_sequence := \p{RI}{2}
Urutan yang menggunakan apa yang disebut tag_base, yang diikuti dengan spesifikasi tag kustom yang terdiri dari berbagai simbol \ x {E0020} - \ x {E007E} dan diakhiri dengan tag_end mark \ x {E007F}.
Unicode mendefinisikannya seperti ini:
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}
Anehnya, Unicode memungkinkan tag didasarkan pada emoji_modifier_sequence atau emoji_presentation_sequence di ED-14a . Tetapi pada saat yang sama dalam ekspresi reguler yang disediakan pada dokumentasi yang sama, ekspresi reguler tampaknya memeriksa urutan berdasarkan satu karakter Emoji saja.
Dalam daftar Unicode 12.1 Emoji hanya ada tiga Emoji yang ditentukan. Semuanya adalah bendera negara Inggris: Inggris ๐ด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ, Skotlandia ๐ด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ dan Wales ๐ด๓ ง๓ ข๓ ท๓ ฌ๓ ณ๓ ฟ. Dan semuanya didasarkan pada satu karakter Emoji. Jadi, sebaiknya kita memeriksa urutan seperti itu saja.
Ekspresi reguler:
\p{Emoji} [\x{E0020}-\x{E007E}]+ \x{E007F}
Penggabung dengan lebar nol adalah skalar \ x {200D}. Dengan bantuannya, beberapa karakter, yang sudah menjadi Emoji sendiri, dapat digabungkan menjadi yang baru.
Misalnya, โkeluarga dengan ayah, putra dan putriโ Emoji ๐จโ๐งโ๐ฆ direproduksi dengan kombinasi ayah ๐จ, anak perempuan ๐ง dan anak laki-laki ๐ฆ Emoji direkatkan dengan simbol ZWJ.
Diperbolehkan untuk menyatukan elemen, yaitu karakter Emoji Tunggal, urutan Presentasi dan Pengubah.
Ekspresi reguler untuk urutan tersebut secara umum terlihat seperti ini:
emoji_zwj_sequence := emoji_zwj_element (\x{200d} emoji_zwj_element )+
Semua representasi Emoji yang disebutkan di atas dapat dijelaskan dengan satu ekspresi reguler:
\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}]
)
)*
saya memiliki masalah yang sama dan akhirnya membuat String
dan Character
ekstensi.
Kode terlalu panjang untuk dikirim karena sebenarnya mencantumkan semua emoji (dari daftar unicode resmi v5.0) di a CharacterSet
Anda dapat menemukannya di sini:
https://github.com/piterwilson/StringEmoji
Kumpulan karakter yang berisi semua emoji yang diketahui (seperti yang dijelaskan dalam Unicode List 5.0 resmi http://unicode.org/emoji/charts-5.0/emoji-list.html )
Apakah String
instance mewakili satu karakter Emoji yang diketahui atau tidak
print("".isEmoji) // false
print("๐".isEmoji) // true
print("๐๐".isEmoji) // false (String is not a single Emoji)
var berisiEmoji: Bool {get}
Apakah String
instance berisi karakter Emoji yang diketahui atau tidak
print("".containsEmoji) // false
print("๐".containsEmoji) // true
print("๐๐".containsEmoji) // true
var unicodeName: String {get}
Menerapkan kCFStringTransformToUnicodeName
- CFStringTransform
pada salinan String
print("รก".unicodeName) // \N{LATIN SMALL LETTER A WITH ACUTE}
print("๐".unicodeName) // "\N{FACE WITH STUCK-OUT TONGUE AND WINKING EYE}"
var niceUnicodeName: String {get}
Mengembalikan hasil dari a kCFStringTransformToUnicodeName
- CFStringTransform
dengan \N{
prefiks dan }
sufiks dihapus
print("รก".unicodeName) // LATIN SMALL LETTER A WITH ACUTE
print("๐".unicodeName) // FACE WITH STUCK-OUT TONGUE AND WINKING EYE
Apakah Character
instance mewakili karakter Emoji yang diketahui atau tidak
print("".isEmoji) // false
print("๐".isEmoji) // true