neena
neena

Reputation: 581

Regular expression for counting words in a sentence

public static int getWordCount(String sentence) {
    return sentence.split("(([a-zA-Z0-9]([-][_])*[a-zA-Z0-9])+)", -1).length
         + sentence.replaceAll("([[a-z][A-Z][0-9][\\W][-][_]]*)", "").length() - 1;
}

My intention is to count the number of words in a sentence. The input to this function is the the lengthy sentence. It may have 255 words.

  1. The word should take hyphens or underscores in between
  2. Function should only count valid words means special character should not be counted eg. &&&& or #### should not count as a word.

The above regular expression is working fine, but when hyphen or underscore comes in between the word eg: co-operation, the count returning as 2, it should be 1. Can anyone please help?

Upvotes: 7

Views: 17263

Answers (4)

Jakub Krhovják
Jakub Krhovják

Reputation: 166

With java 8

public static int getColumnCount(String row) {
    return (int) Pattern.compile("[\\w-]+")
        .matcher(row)
        .results()
        .count();
}

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476554

Instead of using .split and .replaceAll which are quite expensive operations, please use an approach with constant memory usage.

Based on your specifications, you seem to look for the following regex:

[\w-]+

Next you can use this approach to count the number of matches:

public static int getWordCount(String sentence) {
    Pattern pattern = Pattern.compile("[\\w-]+");
    Matcher  matcher = pattern.matcher(sentence);
    int count = 0;
    while (matcher.find())
        count++;
    return count;
}

online jDoodle demo.

This approach works in (more) constant memory: when splitting, the program constructs an array, which is basically useless, since you never inspect the content of the array.

If you don't want words to start or end with hyphens, you can use the following regex:

\w+([-]\w+)*

Upvotes: 10

griFlo
griFlo

Reputation: 2164

if you can use java 8:

long wordCount = Arrays.stream(sentence.split(" ")) //split the sentence into words   
.filter(s -> s.matches("[\\w-]+")) //filter only matching words
.count();

Upvotes: 2

Jongware
Jongware

Reputation: 22457

This part ([-][_])* is wrong. The notation [xyz] means "any single one of the characters inside the brackets" (see http://www.regular-expressions.info/charclass.html). So effectively, you allow exactly the character - and exactly the character _, in that order.

Fixing your group makes it work:

[a-zA-Z0-9]+([-_][a-zA-Z0-9]+)*

and it can be further simplified using \w to

\w+(-\w+)*

because \w matches 0..9, A..Z, a..z and _ (http://www.regular-expressions.info/shorthand.html) and so you only need to add -.

Upvotes: 3

Related Questions