I would like to highlight all of the substring which are inside square brackets, ex: "[Toto] is [doing a lot of] stuff at the same time."
I know how to extract it.
I know how to highlight:
val str = SpannableString("Toto is doing a lot of stuff at the same time.")
str.setSpan(BackgroundColorSpan(Color.YELLOW), 0, 4, 0)
str.setSpan(BackgroundColorSpan(Color.YELLOW), 8, 22 , 0)
textView.text = str
But the problem is I don't know how to achieve both together.
I obviously want to remove the square bracket after have applied the highlight effect but when I do a toString()
then a replace()
the highlight is removed.
Also, the highlight is made with index, and I don't want to extract the substring but let it in the original string, I don't know by which optimized way I should achieve that.
Maybe it's better not to use regex
in order to extract the texts between close brackets. I think it increases the complexity of this job. Using a simple iteration over the text, we can achieve the result in linear complexity.
val text = "[Toto] is [doing a lot of] stuff at the same time."
val spanStack = Stack<Pair<Int, Int>>()
var index = 0
text.forEach {
when (it) {
'[' -> spanStack.push(index to index)
']' -> spanStack.push(spanStack.pop().first to index)
else -> index++
}
}
val spannableString = text
.replace("[\\[\\]]".toRegex(), "")
.let { SpannableString(it) }
.apply {
spanStack.forEach {
setSpan(
BackgroundColorSpan(Color.YELLOW),
it.first,
it.second,
SpannableString.SPAN_INCLUSIVE_INCLUSIVE
)
}
}
textView.text = spannableString
Result: