检测具有@或#的单词并将onClick事件传递给它

时间:2014-11-24 16:58:43

标签: android regex onclick spannablestring

基本上我有一个看起来像Instagram标题的字符串:

  

@username text text emoji @ username2 #hastag text text#hastag2

这里的主要问题是我可以在@或#字符前面放一个表情符号,所以我需要解析文本并找到它们,即使它们被表情符号包围。运行后,我应该为@username@username2#hashtag#hashtag2点击活动。

到目前为止,我做到了:

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());

这适用于没有表情符号的情况。如何在所有场景中完成这项工作?

2 个答案:

答案 0 :(得分:2)

您可以使用此正则表达式从@#开始匹配:

[@#]\w+\b

RegEx Demo

在Java中:

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

PS:您需要在Java中使用PatternMatcher类来获取所有匹配项。

答案 1 :(得分:1)

您需要创建一个正则表达式Pattern,然后从中获取一个Matcher实例。然后你可以迭代匹配:

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);
}

如果要包含下划线,可以使用@anubhava建议的RegEx(相当于[#@][a-zA-Z0-9_]+)。