【问题标题】:How to replace emoji characters with their descriptions in a Swift string如何用 Swift 字符串中的描述替换表情符号字符
【发布时间】:2016-06-11 17:27:54
【问题描述】:

我正在寻找一种将表情符号字符替换为 Swift 字符串中的描述的方法。

例子:

输入"This is my string ????"

我想更换 ????得到:

输出"This is my string {SMILING FACE WITH OPEN MOUTH AND SMILING EYES}"

到目前为止,我使用的是从 this answer by MartinR 的原始代码修改而来的代码,但它仅在处理单个字符时才有效。

let myCharacter : Character = "????"
let cfstr = NSMutableString(string: String(myCharacter)) as CFMutableString
var range = CFRangeMake(0, CFStringGetLength(cfstr))
CFStringTransform(cfstr, &range, kCFStringTransformToUnicodeName, Bool(0))
var newStr = "\(cfstr)"

// removing "\N"  from the result: \N{SMILING FACE WITH OPEN MOUTH AND SMILING EYES}
newStr = newStr.stringByReplacingOccurrencesOfString("\\N", withString:"")

print("\(newStr)") // {SMILING FACE WITH OPEN MOUTH AND SMILING EYES}

我怎样才能做到这一点?

【问题讨论】:

  • 你一般应该注意你是从this answer by MartinR得到的原始代码
  • 完成,感谢您对 luk2302 的评论。

标签: xcode string swift emoji


【解决方案1】:

首先不要使用Character,而是使用String作为输入:

let cfstr = NSMutableString(string: "This ? is my string ?") as CFMutableString

最终会输出

这张{SMILING FACE WITH OPEN HOUTH AND SMILING EYES}是我的字符串{SMILING FACE WITH OPEN MOUTH AND SMILING EYES}

放在一起:

func transformUnicode(input : String) -> String {
    let cfstr = NSMutableString(string: input) as CFMutableString
    var range = CFRangeMake(0, CFStringGetLength(cfstr))
    CFStringTransform(cfstr, &range, kCFStringTransformToUnicodeName, Bool(0))
    let newStr = "\(cfstr)"
    return newStr.stringByReplacingOccurrencesOfString("\\N", withString:"")
}

transformUnicode("This ? is my string ?")

【讨论】:

  • 非常感谢 luk2302,有没有办法限制转换为表情符号,避免处理双引号等其他字符?如果可能的话,我想避免用“左双引号”替换例如“”。
  • @Tel 我不认为有一个简单的方法。它转换所有非 ASCII 字符。系统不知道笑脸到底是什么,顾名思义,它只是一个字符。它看起来像笑脸这一事实只是人类对 unicode 视觉表示的感知。您可能能够做的是找出您想要替换的笑脸具有哪些 unicode charcode 并仅转换这些字符。但这需要你做一些工作。
  • @EricD 老实说,我什至没有更多地研究实际执行的转换,我很惊讶有人认为这甚至是可能的。 OP的代码来自的链接问题中是否已经提到了该替代方案?您可能也想在此处添加它!
【解决方案2】:

这是一个完整的实现。

它也避免将非表情符号字符转换为描述(例如,它避免将 转换为 {LEFT DOUBLE QUOTATION MARK})。为此,它使用了一个基于this answer by Arnold 的扩展,无论字符串是否包含表情符号,它都会返回真或假。

代码的另一部分是基于this answer by MartinRthis answer by luk2302的答案和cmets。

var str = "Hello World ? …" // our string (with an emoji and a horizontal ellipsis)

let newStr = str.characters.reduce("") { // loop through str individual characters
    var item = "\($1)" // string with the current char
    let isEmoji = item.containsEmoji // true or false
    if isEmoji {
        item = item.stringByApplyingTransform(String(kCFStringTransformToUnicodeName), reverse: false)!
    }
    return $0 + item
}.stringByReplacingOccurrencesOfString("\\N", withString:"") // strips "\N"


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:   // Various (e.g. ?)
                return true
            default:
                continue
            }
        }
        return false
    }
}

print (newStr) // Hello World {SMILING FACE WITH OPEN MOUTH AND SMILING EYES} …

请注意,某些表情符号不能包含在此代码的范围内,因此您应该在实施代码时检查是否所有表情符号都已转换。

【讨论】:

  • 我稍微重构了代码:pastebin.com/qxtWuYNd 主要是添加了reduce,我删除了在闭包外部定义但在其中使用的变量,并将替换移到了关闭。
猜你喜欢
  • 2014-09-02
  • 2023-03-03
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 2016-08-16
  • 2016-03-22
  • 2016-01-04
  • 1970-01-01
相关资源
最近更新 更多