diff --git a/Sources/Emoji/String+Emoji.swift b/Sources/Emoji/String+Emoji.swift index 4be8413..d103e47 100644 --- a/Sources/Emoji/String+Emoji.swift +++ b/Sources/Emoji/String+Emoji.swift @@ -8,15 +8,48 @@ import Foundation - extension String { + public var emojiUnescapedString: String { + var s = self as NSString + Emoji.unescapeRegExp? + .matches(in: self, options: [], range: NSMakeRange(0, s.length)) + .reversed() + .forEach { m in + let r = m.range + let p = s.substring(with: r) + let px = p[p.index(after: p.startIndex) ..< p.index(before: p.endIndex)] + if let i = Emoji.indexedShortnames[String(px)], + let codepoint = Emoji.allCases[i].codepoints.first { + s = s.replacingCharacters(in: r, with: codepoint) as NSString + } + } + return s as String + } + + public var emojiEscapedString: String { + var s = self as NSString + Emoji.escapeRegExp? + .matches(in: self, options: [], range: NSMakeRange(0, s.length)) + .reversed() + .forEach { m in + let r = m.range + let p = s.substring(with: r) + if let i = Emoji.indexedCodepoints[p], + let shortname = Emoji.allCases[i].shortnames.first { + s = s.replacingCharacters(in: r, with: ":\(shortname):") as NSString + } + } + return s as String + } +} - fileprivate static var emojiUnescapeRegExp = createEmojiUnescapeRegExp() - fileprivate static var emojiEscapeRegExp = createEmojiEscapeRegExp() - fileprivate static var indexedShortnames = createIndex(for: \.shortnames) - fileprivate static var indexedCodepoints = createIndex(for: \.codepoints) +fileprivate extension Emoji { + static let unescapeRegExp = createEmojiUnescapeRegExp() + static let escapeRegExp = createEmojiEscapeRegExp() + static let indexedShortnames = createIndex(for: \.shortnames) + static let indexedCodepoints = createIndex(for: \.codepoints) - fileprivate static func createEmojiUnescapeRegExp() -> NSRegularExpression? { + static func createEmojiUnescapeRegExp() -> NSRegularExpression? { let pattern = Emoji.allCases .flatMap { $0.shortnames } .map { ":\(NSRegularExpression.escapedPattern(for: $0)):" } @@ -29,7 +62,7 @@ extension String { return nil } - fileprivate static func createEmojiEscapeRegExp() -> NSRegularExpression? { + static func createEmojiEscapeRegExp() -> NSRegularExpression? { let pattern = Emoji.allCases .flatMap { $0.codepoints } .map { NSRegularExpression.escapedPattern(for: $0) } @@ -44,7 +77,7 @@ extension String { return nil } - fileprivate static func createIndex(for propertyFunction: (Emoji) -> [String]) -> [String: Int] { + static func createIndex(for propertyFunction: (Emoji) -> [String]) -> [String: Int] { Emoji.allCases.reduce([String: Int](), { dict, emoji -> [String: Int] in guard let index = Emoji.allCases.firstIndex(of: emoji) else { return [:] } return propertyFunction(emoji).reduce(dict, { eDict, shortname -> [String: Int] in @@ -54,34 +87,4 @@ extension String { }) }) } - - public var emojiUnescapedString: String { - var s = self as NSString - let ms = String.emojiUnescapeRegExp?.matches(in: self, options: [], range: NSMakeRange(0, s.length)) - ms?.reversed().forEach { m in - let r = m.range - let p = s.substring(with: r) - let px = p[p.index(after: p.startIndex) ..< p.index(before: p.endIndex)] - if let i = String.indexedShortnames[String(px)] { - let e = Emoji.allCases[i] - s = s.replacingCharacters(in: r, with: e.codepoints.first!) as NSString - } - } - return s as String - } - - public var emojiEscapedString: String { - var s = self as NSString - let ms = String.emojiEscapeRegExp?.matches(in: self, options: [], range: NSMakeRange(0, s.length)) - ms?.reversed().forEach { m in - let r = m.range - let p = s.substring(with: r) - if let i = String.indexedCodepoints[p] { - let e = Emoji.allCases[i] - s = s.replacingCharacters(in: r, with: ":\(e.shortnames.first!):") as NSString - } - } - return s as String - } - }