How to use regex in String.contains() method in Java

JavaRegexString

Java Problem Overview


I want to check if a String contains the words "stores", "store", and "product" in that order, no matter what is in between them.

I tried using someString.contains(stores%store%product); and also .contains("stores%store%product");

Do I need to explicitly declare a regex and pass it on the method or can I not pass a regex at all?

Java Solutions


Solution 1 - Java

String.contains

String.contains works with String, period. It doesn't work with regex. It will check whether the exact String specified appear in the current String or not.

Note that String.contains does not check for word boundary; it simply checks for substring.

Regex solution

Regex is more powerful than String.contains, since you can enforce word boundary on the keywords (among other things). This means you can search for the keywords as words, rather than just substrings.

Use String.matches with the following regex:

"(?s).*\\bstores\\b.*\\bstore\\b.*\\bproduct\\b.*"

The RAW regex (remove the escaping done in string literal - this is what you get when you print out the string above):

(?s).*\bstores\b.*\bstore\b.*\bproduct\b.*

The \b checks for word boundary, so that you don't get a match for restores store products. Note that stores 3store_product is also rejected, since digit and _ are considered part of a word, but I doubt this case appear in natural text.

Since word boundary is checked for both sides, the regex above will search for exact words. In other words, stores stores product will not match the regex above, since you are searching for the word store without s.

. normally match any character except a number of new line characters. (?s) at the beginning makes . matches any character without exception (thanks to Tim Pietzcker for pointing this out).

Solution 2 - Java

matcher.find() does what you needed. Example:

Pattern.compile("stores.*store.*product").matcher(someString).find();

Solution 3 - Java

You can simply use matches method of String class.

boolean result = someString.matches("stores.*store.*product.*");

Solution 4 - Java

If you want to check if a string contains substring or not using regex, the closest you can do is by using find() -

    private static final validPattern =   "\\bstores\\b.*\\bstore\\b.*\\bproduct\\b"
    Pattern pattern = Pattern.compile(validPattern);
	Matcher matcher = pattern.matcher(inputString);
	System.out.print(matcher.find()); // should print true or false.

Note the difference between matches() and find(), matches() return true if the whole string matches the given pattern. find() tries to find a substring that matches the pattern in a given input string. Also by using find() you don't have to add extra matching like - (?s).* at the beginning and .* at the end of your regex pattern.

Solution 5 - Java

public static void main(String[] args) {
    String test = "something hear - to - find some to or tows";
    System.out.println("1.result: " + contains("- to -( \\w+) som", test, null));
    System.out.println("2.result: " + contains("- to -( \\w+) som", test, 5));
}
static boolean contains(String pattern, String text, Integer fromIndex){
    if(fromIndex != null && fromIndex < text.length())
        return Pattern.compile(pattern).matcher(text).find();

    return Pattern.compile(pattern).matcher(text).find();
}

1.result: true

2.result: true

Solution 6 - Java

As of Java 11 one can use Pattern#asMatchPredicate which returns Predicate<String>.

String string = "stores%store%product";
String regex = "stores.*store.*product.*";
Predicate<String> matchesRegex = Pattern.compile(regex).asMatchPredicate();

boolean match = matchesRegex.test(string);                   // true

The method enables chaining with other String predicates, which is the main advantage of this method as long as the Predicate offers and, or and negate methods.

String string = "stores$store$product";
String regex = "stores.*store.*product.*";

Predicate<String> matchesRegex = Pattern.compile(regex).asMatchPredicate();
Predicate<String> hasLength = s -> s.length() > 20;

boolean match = hasLength.and(matchesRegex).test(string);    // false

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVipin VermaView Question on Stackoverflow
Solution 1 - JavanhahtdhView Answer on Stackoverflow
Solution 2 - Javaeugene82View Answer on Stackoverflow
Solution 3 - Javasan1deep2set3hiView Answer on Stackoverflow
Solution 4 - JavaP CView Answer on Stackoverflow
Solution 5 - JavaAr majView Answer on Stackoverflow
Solution 6 - JavaNikolas CharalambidisView Answer on Stackoverflow