假设我有两个字符串,

String s1 = "AbBaCca";
String s2 = "bac";

我想执行一个检查,返回s2包含在s1中。我可以这样做:

return s1.contains(s2);

我非常确定contains()是区分大小写的,但是我不能从阅读文档中确定这一点。如果是的话,我想我最好的方法是:

return s1.toLowerCase().contains(s2.toLowerCase());

撇开所有这些不谈,有没有另一种(可能更好的)方法可以在不考虑大小写敏感性的情况下完成这个任务?


当前回答

你可以使用正则表达式,它工作:

boolean found = s1.matches("(?i).*" + s2+ ".*");

其他回答

如果您导入ICU4j,可以创建一些unicode友好的代码。我认为“忽略大小写”对于方法名称来说是有问题的,因为尽管主要强度比较确实忽略大小写,但它被描述为具体内容依赖于区域设置。但希望它以用户期望的方式依赖于语言环境。

public static boolean containsIgnoreCase(String haystack, String needle) {
    return indexOfIgnoreCase(haystack, needle) >= 0;
}

public static int indexOfIgnoreCase(String haystack, String needle) {
    StringSearch stringSearch = new StringSearch(needle, haystack);
    stringSearch.getCollator().setStrength(Collator.PRIMARY);
    return stringSearch.first();
}

Dave L.回答的一个问题是s2包含正则表达式标记,如\d等。

你想在s2上调用Pattern.quote():

Pattern.compile(Pattern.quote(s2), Pattern.CASE_INSENSITIVE).matcher(s1).find();

如果你必须在另一个ASCII字符串中搜索一个ASCII字符串,比如URL,你会发现我的解决方案更好。我测试了icza和我的方法的速度,结果如下:

案例1用了2788 ms - regionMatches 病例2用了1520毫秒

代码:

public static String lowerCaseAscii(String s) {
    if (s == null)
        return null;

    int len = s.length();
    char[] buf = new char[len];
    s.getChars(0, len, buf, 0);
    for (int i=0; i<len; i++) {
        if (buf[i] >= 'A' && buf[i] <= 'Z')
            buf[i] += 0x20;
    }

    return new String(buf);
}

public static boolean containsIgnoreCaseAscii(String str, String searchStr) {
    return StringUtils.contains(lowerCaseAscii(str), lowerCaseAscii(searchStr));
}

你可以使用

org.apache.commons.lang3.StringUtils.containsIgnoreCase("AbBaCca", "bac");

Apache Commons库对于这类事情非常有用。这个特殊的表达式可能比正则表达式更好,因为正则表达式在性能方面总是代价高昂。

有一个简单简洁的方法,使用regex标志(不区分大小写{i}):

 String s1 = "hello abc efg";
 String s2 = "ABC";
 s1.matches(".*(?i)"+s2+".*");

/*
 * .*  denotes every character except line break
 * (?i) denotes case insensitivity flag enabled for s2 (String)
 * */