Extracting hashtags from user input

Viewed 38

I have been asking similar questions before so this may be taken down but I feel like the code I have now should work but it doesn't.

String post [] = new String [100];
System.out.println("\nType your post");
String userPost = input.nextLine();
post[0] = userPost;
                  
String hashtags ="";
for (int i = 0; i<post.length && post[i]!=null;i++){
    String[]words = post[i].split(" ");
    for(int j=0;j<words.length;j++){
        if(words[j].trim().startsWith("#")){
            hashtags+=words[j].trim() + " ";
        }
    }
}
if(hashtags.trim().isEmpty())
    System.out.println("No hashtags were typed");
else 
    System.out.println("Hashtags found: " + hashtags );

I feel like this should work but when running this code, it skips asking for user input and immediately prints No hashtags were typed.

1 Answers

What should you do is to use regular expression Java API, extracting all searched hashtags from the provided String variable with the proper regexp:

import java.util.regex.Matcher;
import java.util.regex.Pattern;


class HashtagsFinder {

public static void main() {
    String input = "#HASHTAGS #HASHTAG #ANOTHER_HASHTAG BUT#THISISNOTAHASHTAG";

    Matcher matcher = Pattern.compile("\\B#\\w+").matcher(input);

    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}

A regular expression passed as the Pattern.compile() argument matches expressions in line with the following rules:

  1. \B - ensure that there is no word boundary at the beginning.
  2. # - ensure that there is exactly one hash char at the beginning of the word - with the previous part, it ensures that the hash char is always at the beginning of the word.
  3. \w+ - match one or more of the possible word character (alphanumeric and undescore), so we won't be collecting expressions with just the hash char.

Output of the code pasted above:

#HASHTAGS
#HASHTAG
#ANOTHER_HASHTAG

What is also important - instead of the standard java.util.regex package, you should use https://github.com/google/re2j, since it's faster and provides safer compliation (standard Java regular expressions library uses backtracking to compile passed regex, which may cause our program to exceed available stack space).

Related