How to check if a String contains another String i

2018-12-31 08:45发布

Say I have two strings,

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

I want to perform a check returning that s2 is contained within s1. I can do this with:

return s1.contains(s2);

I am pretty sure that contains() is case sensitive, however I can't determine this for sure from reading the documentation. If it is then I suppose my best method would be something like:

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

All this aside, is there another (possibly better) way to accomplish this without caring about case-sensitivity?

标签: java string
17条回答
回忆,回不去的记忆
2楼-- · 2018-12-31 08:45

I did a test finding a case-insensitive match of a string. I have a Vector of 150,000 objects all with a String as one field and wanted to find the subset which matched a string. I tried three methods:

  1. Convert all to lower case

    for (SongInformation song: songs) {
        if (song.artist.toLowerCase().indexOf(pattern.toLowercase() > -1) {
                ...
        }
    }
    
  2. Use the String matches() method

    for (SongInformation song: songs) {
        if (song.artist.matches("(?i).*" + pattern + ".*")) {
        ...
        }
    }
    
  3. Use regular expressions

    Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
    Matcher m = p.matcher("");
    for (SongInformation song: songs) {
        m.reset(song.artist);
        if (m.find()) {
        ...
        }
    }
    

Timing results are:

  • No attempted match: 20 msecs

  • To lower match: 182 msecs

  • String matches: 278 msecs

  • Regular expression: 65 msecs

The regular expression looks to be the fastest for this use case.

查看更多
牵手、夕阳
3楼-- · 2018-12-31 08:45
import java.text.Normalizer;

import org.apache.commons.lang3.StringUtils;

public class ContainsIgnoreCase {

    public static void main(String[] args) {

        String in = "   Annulée ";
        String key = "annulee";

        // 100% java
        if (Normalizer.normalize(in, Normalizer.Form.NFD).replaceAll("[\\p{InCombiningDiacriticalMarks}]", "").toLowerCase().contains(key)) {
            System.out.println("OK");
        } else {
            System.out.println("KO");
        }

        // use commons.lang lib
        if (StringUtils.containsIgnoreCase(Normalizer.normalize(in, Normalizer.Form.NFD).replaceAll("[\\p{InCombiningDiacriticalMarks}]", ""), key)) {
            System.out.println("OK");
        } else {
            System.out.println("KO");
        }

    }

}
查看更多
初与友歌
4楼-- · 2018-12-31 08:51

One problem with the answer by Dave L. is when s2 contains regex markup such as \d, etc.

You want to call Pattern.quote() on s2:

Pattern.compile(Pattern.quote(s2), Pattern.CASE_INSENSITIVE).matcher(s1).find();
查看更多
骚的不知所云
5楼-- · 2018-12-31 08:51

You can use

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

The Apache Commons library is very useful for this sort of thing. And this particular one may be better than regular expressions as regex is always expensive in terms of performance.

查看更多
看风景的人
6楼-- · 2018-12-31 08:51
String container = " Case SeNsitive ";
String sub = "sen";
if (rcontains(container, sub)) {
    System.out.println("no case");
}

public static Boolean rcontains(String container, String sub) {

    Boolean b = false;
    for (int a = 0; a < container.length() - sub.length() + 1; a++) {
        //System.out.println(sub + " to " + container.substring(a, a+sub.length()));
        if (sub.equalsIgnoreCase(container.substring(a, a + sub.length()))) {
            b = true;
        }
    }
    return b;
}

Basically, it is a method that takes two strings. It is supposed to be a not-case sensitive version of contains(). When using the contains method, you want to see if one string is contained in the other.

This method takes the string that is "sub" and checks if it is equal to the substrings of the container string that are equal in length to the "sub". If you look at the for loop, you will see that it iterates in substrings (that are the length of the "sub") over the container string.

Each iteration checks to see if the substring of the container string is equalsIgnoreCase to the sub.

查看更多
永恒的永恒
7楼-- · 2018-12-31 08:52

Here's some Unicode-friendly ones you can make if you pull in ICU4j. I guess "ignore case" is questionable for the method names because although primary strength comparisons do ignore case, it's described as the specifics being locale-dependent. But it's hopefully locale-dependent in a way the user would expect.

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();
}
查看更多
登录 后发表回答