【问题标题】:How to use regex in String.contains() method in Java如何在 Java 中的 String.contains() 方法中使用正则表达式
【发布时间】:2013-02-14 08:03:04
【问题描述】:

我想检查一个字符串是否按顺序包含“stores”、“store”和“product”这三个词,无论它们之间是什么。

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

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

【问题讨论】:

    标签: java regex string


    【解决方案1】:

    String.contains

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

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

    正则表达式解决方案

    正则表达式比String.contains 更强大,因为您可以在关键字上强制执行单词边界(除其他外)。这意味着您可以将关键字搜索为 words,而不仅仅是 substrings

    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

    . 通常匹配任何字符除了 a number of new line characters。开头的(?s) 使. 匹配任何字符,无一例外(感谢Tim Pietzcker 指出这一点)。

    【讨论】:

    • 如果字符串包含换行符,您可能需要将(?s) 添加到正则表达式的开头。
    • 我在这样的 URL 中检查它>> stores.nextag.com/store/4908844/product/1070625777/…
    • 你能解释一下这里的第一个反斜杠吗\\b
    • @vipin8169:在字符串中,您需要将\ 加倍以指定单个\,因此\\b 将被解释为\b,如RAW 正则表达式所示。 \b 匹配单词边界,如上所述。
    • 如果需要匹配“.mydomain”。在字符串中。那么它将如何更新正则表达式。我的用例是“www.abc.mydomain.in.io”是否包含.mydomain。与否
    【解决方案2】:

    matcher.find() 可以满足您的需求。示例:

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

    【讨论】:

    • 喜欢这个。我发现 matcher 的正则表达式过于复杂。
    【解决方案3】:

    你可以简单地使用String类的matches方法。

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

    【讨论】:

    • 您需要以.* 开头,否则它只会匹配以stores 开头的字符串。
    • 尝试将整个区域与模式匹配。 看来@shmosel 是对的,不是吗?
    • 嗯,它只是匹配,但不检查字符串是否在任何位置包含模式。这不是 OP 寻找的解决方案,我建议改进正则表达式。
    【解决方案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).* 和 .* 。

    【讨论】:

      【解决方案5】:
      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.结果:真

      【讨论】:

      • fromIndex 被忽略了,不是吗? contains("something", test, 5) =&gt; true
      【解决方案6】:

      Java 11 开始,可以使用返回 Predicate&lt;String&gt;Pattern#asMatchPredicate

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

      该方法能够链接 与其他字符串谓词,只要Predicate 提供andornegate 方法,这是该方法的主要优点。 p>

      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
      

      【讨论】:

        猜你喜欢
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-09
        • 1970-01-01
        • 2021-04-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多