一尘不染

找出“字符串中的字符”是否为表情符号?

swift

我需要找出字符串中的字符是否是表情符号。

例如,我有这个角色:

let string = "😀"
let character = Array(string)[0]

我需要确定该字符是否为表情符号。


阅读 278

收藏
2020-07-07

共1个答案

一尘不染

我偶然发现的是字符,unicode标量和字形之间的区别。

例如,字形👨‍👨‍👧‍👧由7个unicode标量组成:

  • 四个表情符号:👨👩👧👧
  • 每个表情符号之间都有一个特殊字符,其作用类似于字符胶;查看规格以获取更多信息

另一个示例,字形of由2个unicode标量组成:

  • 常规表情符号:👌
  • 肤色调节剂:🏿

最后一个字形1️⃣包含三个unicode字符:

因此,渲染字符时,产生的字形确实很重要。

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版本,请查看包含我的旧代码的要点。

2020-07-07