Java Stringcontains使用模式

Java Stringcontains使用模式,java,regex,string,Java,Regex,String,如果我想使用模式在Java正则表达式中100%克隆StringcontainsCharSequence s:boolean。以下调用是否相同 input.contains(s); 及 类似地,以下代码是否具有相同的功能 Pattern.compile(Pattern.quote(s)).matcher(input).find(); 我假设正则表达式搜索的性能较差,但只有一个常数。这是正确的吗?有没有办法优化正则表达式以模拟包含 我这样问的原因是我有一段围绕模式编写的代码,创建一段使用cont

如果我想使用模式在Java正则表达式中100%克隆StringcontainsCharSequence s:boolean。以下调用是否相同

input.contains(s);

类似地,以下代码是否具有相同的功能

Pattern.compile(Pattern.quote(s)).matcher(input).find();
我假设正则表达式搜索的性能较差,但只有一个常数。这是正确的吗?有没有办法优化正则表达式以模拟包含

我这样问的原因是我有一段围绕模式编写的代码,创建一段使用contains的单独代码似乎是浪费。另一方面,我不希望每个代码都有不同的测试结果,即使是很小的测试结果。例如,是否存在与Unicode相关的差异?

如果需要基于编写.contains-like方法,则应选择以下版本:

如果要使用.matches,请记住:

默认情况下,.*将不匹配换行符,您需要在模式或使用的开始处使用?s内联修饰符 模式开始时的.*将导致太多回溯,可能会出现堆栈溢出异常,或者代码执行可能会冻结。 如果需要基于编写.contains like方法,则应选择以下版本:

如果要使用.matches,请记住:

默认情况下,.*将不匹配换行符,您需要在模式或使用的开始处使用?s内联修饰符 模式开始时的.*将导致太多回溯,可能会出现堆栈溢出异常,或者代码执行可能会冻结。
有两种方法可以查看字符串是否与模式匹配:

return Pattern.compile(Pattern.quote(s)).asPredicate().test(input);


不需要在*上进行匹配。这将匹配实际结果周围的任何内容,只会增加开销。

有两种方法可以查看字符串是否与模式匹配:

return Pattern.compile(Pattern.quote(s)).asPredicate().test(input);


不需要在*上进行匹配。这将匹配实际结果周围的任何内容,只会增加开销。

这只是为了分享我决定如何解决这个小难题。我已经由library重新设计,不采用模式,而是采用谓词,如下所示:

public static Set<String> findAll() {
    return find(input -> true);
}

public static Set<String> findSubstring(String s) {
    return find(input -> input.contains(s));
}

public static Set<String> findPattern(Pattern p) {
    return find(p.asPredicate());
}

public static Set<String> findCaseInsensitiveSubstring(String s) {
    return find(Pattern.compile(Pattern.quote(s), Pattern.CASE_INSENSITIVE).asPredicate());
}

private static Set<String> find(Predicate<String> matcher) {
    var testInput = Set.of("some", "text", "to", "test");
    return testInput.stream().filter(matcher).collect(Collectors.toSet());
}

public static void main(String[] args) {
    System.out.println(findAll());
    System.out.println(findSubstring("t"));
    System.out.println(findPattern(Pattern.compile("^[^s]")));
    System.out.println(findCaseInsensitiveSubstring("T"));
}
我使用了到目前为止所有的评论和答案

请注意,在需要匹配的情况下,也有patternamatchpredicate,例如,对于函数匹配模式


当然,以上只是一个演示,而不是我的解决方案中的实际功能。

这只是为了分享我决定如何解决这个小难题。我已经由library重新设计,不采用模式,而是采用谓词,如下所示:

public static Set<String> findAll() {
    return find(input -> true);
}

public static Set<String> findSubstring(String s) {
    return find(input -> input.contains(s));
}

public static Set<String> findPattern(Pattern p) {
    return find(p.asPredicate());
}

public static Set<String> findCaseInsensitiveSubstring(String s) {
    return find(Pattern.compile(Pattern.quote(s), Pattern.CASE_INSENSITIVE).asPredicate());
}

private static Set<String> find(Predicate<String> matcher) {
    var testInput = Set.of("some", "text", "to", "test");
    return testInput.stream().filter(matcher).collect(Collectors.toSet());
}

public static void main(String[] args) {
    System.out.println(findAll());
    System.out.println(findSubstring("t"));
    System.out.println(findPattern(Pattern.compile("^[^s]")));
    System.out.println(findCaseInsensitiveSubstring("T"));
}
我使用了到目前为止所有的评论和答案

请注意,在需要匹配的情况下,也有patternamatchpredicate,例如,对于函数匹配模式


当然,上面只是一个演示,而不是我的解决方案中的实际函数。

如果需要使用匹配器,请使用Pattern.compilePattern.quotes.matcherinput.find;。默认情况下,.*将不匹配起始或Pattern.DOTALL处所需的换行符,并将导致太多回溯。这与答案Wiktor非常接近。。。想写一封吗?查找和匹配之间有一个有趣的区别。就我个人而言,从运行时的角度来看,使用模式来完成contains所做的事情是浪费时间的。需要编译模式,创建匹配器,然后检查匹配-所有这些只是为了做一个简单的子字符串,如Stringcontains.FYI,Stringcontains比regex contains快得多。我希望您有使用regex contains的要求。@ArunGowda我没有要求,但我有一个原因w.r.t.代码复杂性。如果您需要为此使用匹配器,请使用Pattern.compilePattern.quotes.matcherinput.find;。默认情况下,.*将不匹配起始或Pattern.DOTALL处所需的换行符,并将导致太多回溯。这与答案Wiktor非常接近。。。想写一封吗?查找和匹配之间有一个有趣的区别。就我个人而言,从运行时的角度来看,使用模式来完成contains所做的事情是浪费时间的。需要编译模式,创建匹配器,然后检查匹配-所有这些只是为了做一个简单的子字符串,如Stringcontains.FYI,Stringcontains比regex contains快得多。我希望您有使用regex contains的要求。@ArunGowda我没有要求,但我确实有一个原因w.r.t.代码复杂性。很好。你知道这个发现是否会比模式更快吗?这对我来说是违反直觉的。@MaartenBodewes你不能比较Matcherfind和Pattern.DOTALL。前者允许查找部分匹配,而后者仅启用。来匹配断线字符。很好。你知道这个发现是否会比模式更快吗?这对我来说是违反直觉的。@MaartenBodewes你不能比较Matcherfind和Pattern.DOTALL。前者允许查找部分匹配,而后者仅启用。匹配换行符。没关系,请查看asPredi的源代码
返回s->matchers.find。嗯,是的。没关系,看看asPredicate的源代码:returns->matchers.find。嗯,是的。
public static Set<String> findAll() {
    return find(input -> true);
}

public static Set<String> findSubstring(String s) {
    return find(input -> input.contains(s));
}

public static Set<String> findPattern(Pattern p) {
    return find(p.asPredicate());
}

public static Set<String> findCaseInsensitiveSubstring(String s) {
    return find(Pattern.compile(Pattern.quote(s), Pattern.CASE_INSENSITIVE).asPredicate());
}

private static Set<String> find(Predicate<String> matcher) {
    var testInput = Set.of("some", "text", "to", "test");
    return testInput.stream().filter(matcher).collect(Collectors.toSet());
}

public static void main(String[] args) {
    System.out.println(findAll());
    System.out.println(findSubstring("t"));
    System.out.println(findPattern(Pattern.compile("^[^s]")));
    System.out.println(findCaseInsensitiveSubstring("T"));
}