Basically I have a string which looks like an instagram caption:
@username text text emoji@username2 #hastag text text #hastag2
The main issue here is that I could have a emoji in front of @ or # characters, so I need to parse the text and find the words even if they are surrounded by emoji. After a run I should have click event for @username
,@username2
,#hashtag
and #hashtag2
.
So far I did:
String caption = "@username text text emoji@username2 #hastag text text #hastag2";
SpannableString ss = new SpannableString(caption);
String[] words = caption.split(" ");
for (final String word : words) {
if (word.startsWith("#") || word.startsWith("@")) {
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View textView) {
//Clicked word
}
};
ss.setSpan(clickableSpan, caption.indexOf(word), caption.indexOf(word) + word.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
txtComment.setText(ss);
txtComment.setMovementMethod(LinkMovementMethod.getInstance());
This does work for situations where there are no emoji envolved. How can I make this work on all scenarios ?
You need to create a regular expression Pattern, and then get a Matcher instance from it. Then you can iterate over the matches:
Pattern p = Pattern.compile("[#@][a-zA-Z0-9]+"); //match letters or numbers after a # or @
Matcher m = p.matcher(caption); //get matcher, applying the pattern to caption string
while (m.find()) { // Find each match in turn
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View textView) {
//Clicked word
}
};
ss.setSpan(clickableSpan, m.start(), m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
If you want to include underscores, you can use the RegEx suggested by @anubhava (which is equivalent to [#@][a-zA-Z0-9_]+
).