Swift - 用空格替换字符串中的表情符号

Rap*_*ael 3 string unicode emoji swift

我有一个方法来检测字符串中的网址,并返回网址和可以找到它们的范围.一切都很完美,直到字符串上有表情符号.例如:

"I'm gonna do this callenge as soon as I can swing again \n http://youtu.be/SW_d3fGz1hk"
Run Code Online (Sandbox Code Playgroud)

由于表情符号,从文本中提取的URL是http://youtu.be/SW_d3fGz1而不是http://youtu.be/SW_d3fGz1hk.我认为最简单的解决方案是用空格字符替换字符串上的表情符号(因为我需要范围对于某些文本样式的东西是正确的).问题是,使用Swift非常难以实现(很可能我的Swift String API缺乏能力).

我一直试图这样做,但似乎我无法从unicode点数组创建一个字符串:

var emojilessStringWithSubstitution: String {
    let emojiRanges = [0x1F601...0x1F64F, 0x2702...0x27B0]
    let emojiSet = Set(emojiRanges.flatten())
    let codePoints: [UnicodeScalar] = self.unicodeScalars.map {
        if emojiSet.contains(Int($0.value)) {
            return UnicodeScalar(32)
        }
        return $0
    }
    return String(codePoints)
}
Run Code Online (Sandbox Code Playgroud)

我是否以错误的方式处理这个问题?取代表情符号是最好的解决方案吗?如果是这样,我该怎么办?

dfr*_*fri 8

您可以使用模式匹配(用于表情符号模式)从您的过滤掉表情符号字符String.

extension String {

    var emojilessStringWithSubstitution: String {
        let emojiPatterns = [UnicodeScalar(0x1F601)...UnicodeScalar(0x1F64F),
                             UnicodeScalar(0x2702)...UnicodeScalar(0x27B0)]
        return self.unicodeScalars
            .filter { ucScalar in !(emojiPatterns.contains{ $0 ~= ucScalar }) }
            .reduce("") { $0 + String($1) }
    }  
}

/* example usage */
let str = "I'm gonna do this callenge as soon as I can swing again \n http://youtu.be/SW_d3fGz1hk"
print(str.emojilessStringWithSubstitution)

/* I'm gonna do this callenge as soon as I can swing again
   http://youtu.be/SW_d3fGz1hk */
Run Code Online (Sandbox Code Playgroud)

请注意,上面只使用了问题中提供的表情符号间隔,并不代表所有表情符号,但该方法是通用的,可以通过在emojiPatterns数组中包含额外的表情符号间隔来快速扩展.


我意识到你再次阅读你的问题,你更喜欢用空白字符替换emojis,而不是删除它们(上面的过滤解决方案就是这样).我们可以通过用.filter条件返回.map操作替换上面的操作来实现这一点,就像你的问题一样

extension String {

    var emojilessStringWithSubstitution: String {
        let emojiPatterns = [UnicodeScalar(0x1F600)...UnicodeScalar(0x1F64F),
                         UnicodeScalar(0x1F300)...UnicodeScalar(0x1F5FF),
                         UnicodeScalar(0x1F680)...UnicodeScalar(0x1F6FF),
                         UnicodeScalar(0x2600)...UnicodeScalar(0x26FF),
                         UnicodeScalar(0x2700)...UnicodeScalar(0x27BF),
                         UnicodeScalar(0xFE00)...UnicodeScalar(0xFE0F)]

        return self.unicodeScalars
            .map { ucScalar in
                emojiPatterns.contains{ $0 ~= ucScalar } ? UnicodeScalar(32) : ucScalar }
            .reduce("") { $0 + String($1) }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在上面,已经扩展了现有的表情符号间隔,根据你对这篇文章的评论(列出这些间隔),这样表情符号检查现在可能是详尽无遗的.


Bog*_*kiy 6

斯威夫特 4:

extension String {
  func stringByRemovingEmoji() -> String {
    return String(self.filter { !$0.isEmoji() })
  }
}

extension Character {
  fileprivate func isEmoji() -> Bool {
    return Character(UnicodeScalar(UInt32(0x1d000))!) <= self && self <= Character(UnicodeScalar(UInt32(0x1f77f))!)
      || Character(UnicodeScalar(UInt32(0x2100))!) <= self && self <= Character(UnicodeScalar(UInt32(0x26ff))!)
  }
}
Run Code Online (Sandbox Code Playgroud)


Dil*_*gid 5

表情符号被 Unicode 归类为符号。字符集通常用于搜索操作。所以我们将使用字符集作为符号的属性。

var emojiString =  "Hey there , welcome"
emojiString = emojiString.components(separatedBy: CharacterSet.symbols).joined()       
print(emojiString)
Run Code Online (Sandbox Code Playgroud)

输出是

Hey there , welcome
Run Code Online (Sandbox Code Playgroud)

现在观察表情符号被一个空格替换,所以有两个空格,我们用以下方式替换它

emojiString.replacingOccurrences(of: "  ", with: " ") 
Run Code Online (Sandbox Code Playgroud)

上述方法将参数:“两个空格”替换为:“单个空格”


Abd*_*ish 5

斯威夫特 5

不要用这种hardcoded方式检测emojis. 在Swift 5你可以轻松做到

let inputText = "Some string  with   emoji "

let textWithoutEmoij = inputText.unicodeScalars
    .filter { !$0.properties.isEmojiPresentation}
    .reduce("") { $0 + String($1) }

print(textWithoutEmoij) // Some string  with   emoji 
Run Code Online (Sandbox Code Playgroud)

  • ios 14.0时代支持10.0的应用有哪些?!! (3认同)