1

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 ?

JstnPwll
  • 8,585
  • 2
  • 33
  • 56
Alin
  • 14,809
  • 40
  • 129
  • 218

2 Answers2

2

You can use this regex to get your matches starting with @ or #:

[@#]\w+\b

RegEx Demo

In Java:

Pattern p = Pattern.compile( "[@#]\\w+\\b" );

PS: You will need to use Pattern and Matcher class in Java to get all the matches.

anubhava
  • 761,203
  • 64
  • 569
  • 643
2

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_]+).

JstnPwll
  • 8,585
  • 2
  • 33
  • 56
  • Thanks for the detailed answer, it works. I also used the answer from http://stackoverflow.com/questions/19750458/android-clickablespan-get-text-onclick to fetch the clicked work within onClick – Alin Nov 24 '14 at 17:34
  • Great, I'm glad it fits the bill! – JstnPwll Nov 24 '14 at 17:39