133

我想检查一个字符串是否按顺序包含“商店”、“商店”和“产品”这几个词,无论它们之间是什么。

我尝试使用someString.contains(stores%store%product);并且也.contains("stores%store%product");

我是否需要显式声明一个正则表达式并将其传递给方法,或者我根本不能传递一个正则表达式?

4

6 回答 6

143

字符串.包含

String.contains与字符串、句号一起使用。它不适用于正则表达式。它将检查指定的确切字符串是否出现在当前字符串中。

注意String.contains不检查单词边界;它只是检查子字符串。

正则表达式解决方案

Regex 比 更强大String.contains,因为您可以对关键字强制执行单词边界(除其他外)。这意味着您可以将关键字作为单词进行搜索,而不仅仅是子字符串

String.matches与以下正则表达式一起使用:

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

RAW 正则表达式(删除在字符串文字中完成的转义 - 这是您在打印出上面的字符串时得到的):

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

检查单词边界,\b这样您就不会得到restores store products. 请注意,这stores 3store_product也被拒绝,因为 digit 和_被认为是单词的一部分,但我怀疑这种情况是否出现在自然文本中。

由于两边都检查了单词边界,所以上面的正则表达式将搜索确切的单词。换句话说,stores stores product将不匹配上面的正则表达式,因为您正在搜索store没有s.

.通常匹配 多个换行符之外的任何字符(?s)一开始.匹配任何字符,无一例外(感谢 Tim Pietzcker 指出这一点)。

于 2013-02-28T08:01:48.983 回答
125

matcher.find()做你需要的。例子:

Pattern.compile("stores.*store.*product").matcher(someString).find();
于 2014-06-03T06:45:27.390 回答
24

您可以简单地使用matchesString 类的方法。

boolean result = someString.matches("stores.*store.*product.*");
于 2016-02-29T11:28:08.677 回答
4

如果你想检查一个字符串是否包含子字符串或不使用正则表达式,你可以做的最接近的是使用 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.

请注意matches() 和find() 之间的区别,如果整个字符串与给定模式匹配,matches() 将返回true。find() 尝试查找与给定输入字符串中的模式匹配的子字符串。此外,通过使用 find() 您不必在正则表达式模式的开头添加额外的匹配,例如 - (?s).* 和 .* 。

于 2017-05-16T21:11:02.617 回答
2
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.结果:真

2.结果:真

于 2017-06-01T23:00:06.450 回答
1

Java 11开始,可以使用Pattern#asMatchPredicatewhich 返回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

该方法可以与其他 String 谓词链接,这是该方法的主要优点,只要Predicate提供andornegate方法。

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
于 2020-12-12T23:35:56.763 回答