I have a method that detects urls in a string and returns me both the urls and the ranges where they can be found. Everything works perfectly until there are emojis on the s
You can use pattern matching (for emoji patterns) to filter out emoji characters from your 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
Getting all emoji is more complicated than you would think. For more info on how to figure out which characters are emoji, check out this stackoverflow post or this article.
Building on that information, I would propose to use the extension on Character to more easily let us understand which characters are emoji. Then add a String extension to easily replace found emoji with another character.
extension Character {
var isSimpleEmoji: Bool {
guard let firstProperties = unicodeScalars.first?.properties else {
return false
}
return unicodeScalars.count == 1 &&
(firstProperties.isEmojiPresentation ||
firstProperties.generalCategory == .otherSymbol)
}
var isCombinedIntoEmoji: Bool {
return unicodeScalars.count > 1 &&
unicodeScalars.contains {
$0.properties.isJoinControl ||
$0.properties.isVariationSelector
}
}
var isEmoji: Bool {
return isSimpleEmoji || isCombinedIntoEmoji
}
}
extension String {
func replaceEmoji(with character: Character) -> String {
return String(map { $0.isEmoji ? character : $0 })
}
}
Using it would simply become:
"Some string
Swift 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))!)
}
}
Emojis are classified as symbols by Unicode. Character sets are typically used in searching operations. So we will use Character sets a property that is symbols.
var emojiString = "Hey there
Swift 5
Don't use this hardcoded
way to detect emojis
. In Swift 5
you can do it easily
let inputText = "Some
I found that the solutions given above did not work for certain characters such as