Pattern.asMatchPredicate 和 Pattern.asPredicate 之间的区别

Mar*_*ers 7 java regex java-11

Java 11 向Pattern类(正则表达式的编译版本)添加了一些新方法,包括:

我想了解两者之间的区别以及何时想使用其中一种而不是另一种?

Mar*_*ers 13

  • Pattern.asPredicate如果输入字符串的任何部分与正则表达式匹配,则返回 true 。如果您要针对特定​​模式测试较大的文本正文,则应该使用此方法。例如,测试用户的评论是否包含超链接。
  • Pattern.asMatchPredicate如果整个输入字符串与正则表达式匹配,则返回 true 。如果您正在测试特定模式的整个输入,则应该使用此方法。例如,验证用户个人资料中的电话号码。

Pattern.asPredicate内部使用Matcher.find(),同时Pattern.asMatchPrediate内部使用Matcher.matches()。所以两者之间的区别归结为这两个方法在Matcher类中的区别。

以下是一些展示差异的示例。您可以将以下代码复制并粘贴到在线 Java 沙箱(例如https://www.compilejava.net/ )中,以便自己使用。

import java.util.regex.Pattern;
import java.util.function.Predicate;

public class main
{
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("abc");

        // asPredicate will match any part of the input string
        Predicate<String> asPredicate = pattern.asPredicate();
        
        // True, because abc is part of abc
        System.out.printf("asPredicate: abc: %s\n", asPredicate.test("abc"));

        // True, because abc is part of abcabc
        System.out.printf("asPredicate: abcabc: %s\n", asPredicate.test("abcabc"));

        // True, because abc is part of 123abc123
        System.out.printf("asPredicate: 123abc123: %s\n", asPredicate.test("123abc123"));

        // False, because abc is NOT part of 123
        System.out.printf("asPredicate: 123: %s\n", asPredicate.test("123")); // -> false

        // asMatchPredicate will only match the entire input string
        Predicate<String> asMatchPredicate = pattern.asMatchPredicate();

        // True, because abc exactly matches abc
        System.out.printf("asMatchPredicate: abc: %s\n", asMatchPredicate.test("abc"));

        // False, because abc does not exactly match abcabc
        System.out.printf("asMatchPredicate: abcabc: %s\n", asMatchPredicate.test("abcabc"));

        // False, because abc does not exactly match 123abc123
        System.out.printf("asMatchPredicate: 123abc123: %s\n", asMatchPredicate.test("123abc123"));

        // False, because abc does not exactly match 123
        System.out.printf("asMatchPredicate: 123: %s\n", asMatchPredicate.test("123"));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 它“应该”是等价的,但事实并非如此。我刚刚做了一些测试,发现了一个矛盾。然后,我搜索了bug列表,发现[我不是第一个](https://bugs.openjdk.java.net/browse/JDK-8218146)。我认为,用`^`和`$`来解释是没有必要的。`find` 和 `matches` 的语义(这些操作也在幕后实际使用)更重要且更容易记住,因为“`asMatchPredicate` 使用 `matches`”。 (3认同)
  • `^` 和 `$` 不匹配换行符,除非[多行模式](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util /regex/Pattern.html#MULTILINE) 已打开。 (2认同)