views:

137

answers:

6

We have a string input and the following combinations are valid (e.g. sunday, *sunday*, sun*day*, *sun*day, su*nda*y) If it contains only a single asterisk, then it is a bad input.

So given the above input, how do I check to see if the string contains multiple asterisks.

+1  A: 

At least two ways:

  • regex

    String regex = ".*\\*.*\\*.*";
    boolean valid = input.matches(regex);
    
  • loop

    int asterisks = 0;
    for (int i = 0; i < input.length(); i ++) {
        if (input.charAt(i) == '*') {
            asterisks++;
        }
    }
    
Bozho
You could remove the `.*` from the front and end of the regex and use `find()` instead. That might actually be a bit faster.
Joachim Sauer
+2  A: 

You could use String.matches with a regular expression:

"^.*(?:\\*.*){2}$"

If you want exactly two asterisks:

"^[^*]*(?:\\*[^*]*){2}$"

Though for this task it might be simpler just to iterate over the string and count the asterisks.

Mark Byers
+4  A: 
int asterisk1 = input.indexOf('*');
boolean hasTowAsterisks = asterisk1 != -1 && input.indexOf('*', asterisk1+1) != -1;

Edit: this solution assumed that the requirement was "has at least two asterisks".

Joachim Sauer
+1  A: 
boolean hasTwoAsteriks(String str) {
int i;
if((i = str.indexOf("*")) != -1) {
  if ((i = str.indexOf("*", i+1)) != -1)
    return true;
return false;
}
bhups
+2  A: 

Here's a non-regex alternative that works with any literal string:

public static boolean containsNoneOrTwo(String haystack, String needle) {
    int index = haystack.indexOf(needle);
    return (index == -1) ||
        haystack.indexOf(needle, index+1) == haystack.lastIndexOf(needle);
}

Essentially the algorithm is:

containsNoneOrTwo(haystack, needle)
   = haystack contains no needle OR
        haystack's second needle is also its last
polygenelubricants
Joachim Sauer
A: 

For completeness (although several good answers have been provided, I like Mark's and Joachim's best), here are two versions based on String.split(regex) and String.split(regex, limit):

(Edit, bug fix:)

boolean containsAtLeastTwoAsterisks = ("_" + myString + "_").split("\\*", 3).length == 3;

boolean containsExactlyTwoAsterisks = ("_" + myString + "_").split("\\*").length == 3;

I wrote a little benchmark based on our answers (I know, benchmarks don't mean much, but they are fun, and mine is probably crap, I know.) Anyway, here are the results for a sample run:

*********************************************************************************

Testing strings with one or less asterisk

Processor: bhups
Finished. Duration: 40 ms, errors: 0

Processor: Bozho (loop version)
Finished. Duration: 33 ms, errors: 0

Processor: Bozho (regex version)
Finished. Duration: 806 ms, errors: 0

Processor: Joachim Sauer
Finished. Duration: 24 ms, errors: 0 <-- winner

Processor: Mark Byers
Finished. Duration: 1068 ms, errors: 0

Processor: seanizer
Finished. Duration: 408 ms, errors: 0

*********************************************************************************

Testing strings with exactly two asterisks

Processor: bhups
Finished. Duration: 14 ms, errors: 0 <-- winner

Processor: Bozho (loop version)
Finished. Duration: 21 ms, errors: 0

Processor: Bozho (regex version)
Finished. Duration: 693 ms, errors: 0

Processor: Joachim Sauer
Finished. Duration: 14 ms, errors: 0 <-- winner

Processor: Mark Byers
Finished. Duration: 491 ms, errors: 0

Processor: seanizer
Finished. Duration: 340 ms, errors: 0

*********************************************************************************

Testing strings with more than two asterisks (not all processors will be included)

Skipping processor bhups

Processor: Bozho (loop version)
Finished. Duration: 63 ms, errors: 0  <-- winner

Skipping processor Bozho (regex version)

Skipping processor Joachim Sauer

Processor: Mark Byers
Finished. Duration: 1555 ms, errors: 0

Processor: seanizer
Finished. Duration: 860 ms, errors: 0

Seems like non-regex is a lot faster than regex. That's what you'ld expect, I guess.

EDIT: fixed wrong winner. sorry, joachim

seanizer
Is 33 < 24? ;-)
Joachim Sauer
you're right, I found it myself just before reading your comment. fixed it.
seanizer