I have a label where I have normal text and hashtags. I wanted the hashtags to have a different color, so I did something like this:
let text = "#hellothere I am you. #hashtag #hashtag2 @you #hashtag3"
let words = text.components(separatedBy: " ")
let attribute = NSMutableAttributedString.init(string: text)
for word in words {
let range = (text as NSString).range(of: word)
if word.hasPrefix("#") {
attribute.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: range)
}
}
label.attributedText = attribute
However, when i am using this logic, the results are inconsistent. Sometimes, the hashtags get colored as expected, other times some portion of the word containing the hashtag gets colored along with some portion of the next word. I am looking for a solution where I can identify if there is a "#" character in the word (the first occurrence in the word only) and then color the word from the hashtag till the next whitespace, comma, semicolon, full stop or end of string, whichever may be applicable.
This calls for a regular expression. Example in Swift 3.
let attrStr = NSMutableAttributedString(string: "#hellothere I am you. #hashtag, #hashtag2 @you #hashtag3")
let searchPattern = "#\\w+"
var ranges: [NSRange] = [NSRange]()
let regex = try! NSRegularExpression(pattern: searchPattern, options: [])
ranges = regex.matches(in: attrStr.string, options: [], range: NSMakeRange(0, attrStr.string.characters.count)).map {$0.range}
for range in ranges {
attrStr.addAttribute(NSForegroundColorAttributeName, value: UIColor.yellow, range: NSRange(location: range.location, length: range.length))
}
attrStr
Paste the above into a playground and look at the output. To see the regex in action try this link.