465

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?

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Aaron
  • 23,450
  • 10
  • 49
  • 48
  • 35
    I think you've answered your own question. I don't think any of the solutions below are better than this. But they are definitely slower. – Nikolay Dimitrov Oct 16 '14 at 16:16
  • 11
    Your solution is simpler thant any of the ones in the answers – LobsterMan Nov 16 '17 at 17:06
  • 1
    [DrJava](http://drjava.sourceforge.net/) would be an extremely easy way to test this when the documentation fails you. Just type a couple of test cases into its Interactions window, and you should find out. – EfForEffort Sep 17 '08 at 19:41
  • 4
    Your example is the simplest, most readable, and probably the best way to do this - better than any of the answers I'm seeing. – user1258361 Aug 12 '19 at 21:06
  • 1
    [*Does your code pass The Turkey Test?*](http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html) – Basil Bourque Sep 01 '22 at 16:37

20 Answers20

353

Yes, contains is case sensitive. You can use java.util.regex.Pattern with the CASE_INSENSITIVE flag for case insensitive matching:

Pattern.compile(Pattern.quote(wantedStr), Pattern.CASE_INSENSITIVE).matcher(source).find();

EDIT: If s2 contains regex special characters (of which there are many) it's important to quote it first. I've corrected my answer since it is the first one people will see, but vote up Matt Quail's since he pointed this out.

Mike
  • 14,010
  • 29
  • 101
  • 161
Dave L.
  • 43,907
  • 11
  • 63
  • 62
  • 25
    As stated by the documentation for `Pattern.CASE_INSENSITIVE`, this works only for ASCII characters (i.e., "Ä" won't match "ä"). One needs to additionally specify the `UNICODE_CASE` flag to achive that. – Philipp Wendler May 15 '12 at 14:49
  • 89
    is this approach using `Pattern` more performant than `s1.toLowerCase().contains(s2.toLowerCase())` ? – Rajat Gupta Aug 09 '12 at 10:24
  • The first try it doesnt work then I changed s2 <-> s1 , it works. – Günay Gültekin Apr 08 '13 at 20:17
  • 1
    @GünayGültekin That is odd. The code as given returns `true` and appears correct but if I switch s2 and s1, then it returns `false`. Could you have your definitions mixed up? – Dave L. Apr 09 '13 at 17:01
  • Does it need less performance then toLowerCase()? Even in long Strings? When no, why should i use it? This method is "long" to write, too. For me it looks less readable. – xoned Sep 02 '13 at 13:58
  • 7
    @user01 I performed a speed analysis. See my answer for the results (I also showed a faster solution): http://stackoverflow.com/a/25379180/1705598 – icza Aug 19 '14 at 09:15
  • Using `Pattern.LITERAL` would be faster than `Pattern.quote`. – Boann Nov 04 '14 at 13:08
  • 13
    It would me more clear what was going on if we had better variable names: `Pattern.compile(Pattern.quote(needle), Pattern.CASE_INSENSITIVE).matcher(haystack).find()` – John Bowers Feb 19 '15 at 16:16
  • 7
    @user01 correctness comes before performance, and using toLowerCase will give potentially incorrect results (for example, when comparing certain Greek text containing the letter Sigma, which has two lowercase forms for the same uppercase form). – Klitos Kyriacou May 20 '15 at 09:52
  • While you're right that it's usually better to be correct than fast, that's not always the case. I'm still hoping to find something both fast and accurate. – Nathan Loyer Mar 22 '19 at 01:00
  • You can simply convert both strings to lower case like this: string.toLowerCase().contains("someExampleString".toLowerCase());. – Zia Aug 04 '20 at 04:16
293

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();
Community
  • 1
  • 1
Matt Quail
  • 6,189
  • 2
  • 23
  • 20
  • 1
    Nice catch Matt. I'm curious to know what method is more efficient - the lowercase contains, or your pattern solution. Isn't using a pattern less efficient for a single comparison, but more efficient for multiple comparisons? – Aaron Sep 18 '08 at 16:55
  • 47
    The .toLowerCase().contains() method will probably be faster in most cases. I would probably prefer that style for lower complexity, too. – Matt Quail Sep 19 '08 at 00:09
  • 4
    @AaronFerguson Yes, indeed, `toLowerCase().contains()` is faster. I performed some speed analysis, see my answer for results: http://stackoverflow.com/a/25379180/1705598 – icza Aug 19 '14 at 09:16
  • 2
    @MattQuail there's no point in it being faster if it may be incorrect. For example, the Greek capital sigma has two lowercase forms (depending on whether it comes at the end of a word or not) and when attempting to do case-insensitive substring match, where the substring ends with a sigma, you could easily get incorrect results. – Klitos Kyriacou May 20 '15 at 09:55
  • I think we should add `Pattern.UNICODE_CASE` flag too. Could you please confirm this? – Thariq Nugrohotomo Jul 20 '16 at 08:55
218

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matto
  • 2,538
  • 2
  • 18
  • 23
  • 2
    Does anybody know if this respects locale? – Charles Wood Mar 11 '14 at 18:33
  • 13
    @CharlesWood It delegates to `String.regionMatches`, which uses character-wise conversions, so no. Moreover, `containsIgnoreCase("ß", "ss")` returns -1, which is wrong in every locale (the German "sharp s" capitalizes to "ss". – maaartinus Oct 03 '14 at 14:16
  • Which would be the right way of comparing german words then? It seems that is one language that complicates every way of comparing strings :P – chomp Mar 24 '19 at 00:13
  • 1
    BTW: the German language was officially extended with a capital ß in 2017: https://de.wikipedia.org/wiki/Gro%C3%9Fes_%C3%9F. On German keyboards, type Shift + Alt Gr + ß -> test: ẞ – Kawu Nov 23 '19 at 13:12
  • Similar you may have the problem in capitalilzation/lowercasing the dotted & dotless i <-> İ and ı <-> I in turkish language (e.g. in İstanbul) vs. many non-turk languages using actually slightly distinct vowels for capital/lower cases I <-> i. – stefan123t Nov 12 '20 at 13:43
  • @stefan123t Have you tried to normalize the test before comparing? `java.text.Normalizer`. I admit it's annoying though. Another thing you can do is to use an implementation of Metaphone algorithm. Maybe this one https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/language/Metaphone.html is a good start. Even though, It matches "Istanbul", "ıstanbul" but not "İstanbul", "ıstanbul" nor "İstanbul", "istanbul" – Matto Aug 17 '21 at 09:43
144

A Faster Implementation: Utilizing String.regionMatches()

Using regexp can be relatively slow. It (being slow) doesn't matter if you just want to check in one case. But if you have an array or a collection of thousands or hundreds of thousands of strings, things can get pretty slow.

The presented solution below doesn't use regular expressions nor toLowerCase() (which is also slow because it creates another strings and just throws them away after the check).

The solution builds on the String.regionMatches() method which seems to be unknown. It checks if 2 String regions match, but what's important is that it also has an overload with a handy ignoreCase parameter.

public static boolean containsIgnoreCase(String src, String what) {
    final int length = what.length();
    if (length == 0)
        return true; // Empty string is contained
        
    final char firstLo = Character.toLowerCase(what.charAt(0));
    final char firstUp = Character.toUpperCase(what.charAt(0));
    
    for (int i = src.length() - length; i >= 0; i--) {
        // Quick check before calling the more expensive regionMatches() method:
        final char ch = src.charAt(i);
        if (ch != firstLo && ch != firstUp)
            continue;
        
        if (src.regionMatches(true, i, what, 0, length))
            return true;
    }
    
    return false;
}

Speed Analysis

This speed analysis does not mean to be rocket science, just a rough picture of how fast the different methods are.

I compare 5 methods.

  1. Our containsIgnoreCase() method.
  2. By converting both strings to lower-case and call String.contains().
  3. By converting source string to lower-case and call String.contains() with the pre-cached, lower-cased substring. This solution is already not as flexible because it tests a predefiend substring.
  4. Using regular expression (the accepted answer Pattern.compile().matcher().find()...)
  5. Using regular expression but with pre-created and cached Pattern. This solution is already not as flexible because it tests a predefined substring.

Results (by calling the method 10 million times):

  1. Our method: 670 ms
  2. 2x toLowerCase() and contains(): 2829 ms
  3. 1x toLowerCase() and contains() with cached substring: 2446 ms
  4. Regexp: 7180 ms
  5. Regexp with cached Pattern: 1845 ms

Results in a table:

                                            RELATIVE SPEED   1/RELATIVE SPEED
 METHOD                          EXEC TIME    TO SLOWEST      TO FASTEST (#1)
------------------------------------------------------------------------------
 1. Using regionMatches()          670 ms       10.7x            1.0x
 2. 2x lowercase+contains         2829 ms        2.5x            4.2x
 3. 1x lowercase+contains cache   2446 ms        2.9x            3.7x
 4. Regexp                        7180 ms        1.0x           10.7x
 5. Regexp+cached pattern         1845 ms        3.9x            2.8x

Our method is 4x faster compared to lowercasing and using contains(), 10x faster compared to using regular expressions and also 3x faster even if the Pattern is pre-cached (and losing flexibility of checking for an arbitrary substring).


Analysis Test Code

If you're interested how the analysis was performed, here is the complete runnable application:

import java.util.regex.Pattern;

public class ContainsAnalysis {
    
    // Case 1 utilizing String.regionMatches()
    public static boolean containsIgnoreCase(String src, String what) {
        final int length = what.length();
        if (length == 0)
            return true; // Empty string is contained
            
        final char firstLo = Character.toLowerCase(what.charAt(0));
        final char firstUp = Character.toUpperCase(what.charAt(0));
        
        for (int i = src.length() - length; i >= 0; i--) {
            // Quick check before calling the more expensive regionMatches()
            // method:
            final char ch = src.charAt(i);
            if (ch != firstLo && ch != firstUp)
                continue;
            
            if (src.regionMatches(true, i, what, 0, length))
                return true;
        }
        
        return false;
    }
    
    // Case 2 with 2x toLowerCase() and contains()
    public static boolean containsConverting(String src, String what) {
        return src.toLowerCase().contains(what.toLowerCase());
    }
    
    // The cached substring for case 3
    private static final String S = "i am".toLowerCase();
    
    // Case 3 with pre-cached substring and 1x toLowerCase() and contains()
    public static boolean containsConverting(String src) {
        return src.toLowerCase().contains(S);
    }
    
    // Case 4 with regexp
    public static boolean containsIgnoreCaseRegexp(String src, String what) {
        return Pattern.compile(Pattern.quote(what), Pattern.CASE_INSENSITIVE)
                    .matcher(src).find();
    }
    
    // The cached pattern for case 5
    private static final Pattern P = Pattern.compile(
            Pattern.quote("i am"), Pattern.CASE_INSENSITIVE);
    
    // Case 5 with pre-cached Pattern
    public static boolean containsIgnoreCaseRegexp(String src) {
        return P.matcher(src).find();
    }
    
    // Main method: perfroms speed analysis on different contains methods
    // (case ignored)
    public static void main(String[] args) throws Exception {
        final String src = "Hi, I am Adam";
        final String what = "i am";
        
        long start, end;
        final int N = 10_000_000;
        
        start = System.nanoTime();
        for (int i = 0; i < N; i++)
            containsIgnoreCase(src, what);
        end = System.nanoTime();
        System.out.println("Case 1 took " + ((end - start) / 1000000) + "ms");
        
        start = System.nanoTime();
        for (int i = 0; i < N; i++)
            containsConverting(src, what);
        end = System.nanoTime();
        System.out.println("Case 2 took " + ((end - start) / 1000000) + "ms");
        
        start = System.nanoTime();
        for (int i = 0; i < N; i++)
            containsConverting(src);
        end = System.nanoTime();
        System.out.println("Case 3 took " + ((end - start) / 1000000) + "ms");
        
        start = System.nanoTime();
        for (int i = 0; i < N; i++)
            containsIgnoreCaseRegexp(src, what);
        end = System.nanoTime();
        System.out.println("Case 4 took " + ((end - start) / 1000000) + "ms");
        
        start = System.nanoTime();
        for (int i = 0; i < N; i++)
            containsIgnoreCaseRegexp(src);
        end = System.nanoTime();
        System.out.println("Case 5 took " + ((end - start) / 1000000) + "ms");
    }
    
}
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
icza
  • 389,944
  • 63
  • 907
  • 827
  • 7
    +1 but note that it fails for `ß` (German sharp S; capitalizes to `SS`) and also for some other characters (see the source of `String.regionMatches`, which tries both conversions). – maaartinus Oct 03 '14 at 14:25
  • 2
    Your always tests the same strings, which is not really a fair comparison. 'i am' is always in the middle, which might or might not make a difference for the different search methods. Better would be to generate random strings and also report on the speed when a substring is not present. –  Oct 12 '14 at 14:11
  • 2
    That seems really close to Apache StringUtils method : http://grepcode.com/file/repo1.maven.org/maven2/org.apache.commons/commons-lang3/3.1/org/apache/commons/lang3/StringUtils.java#StringUtils.containsIgnoreCase%28java.lang.CharSequence%2Cjava.lang.CharSequence%29 – alain.janinm Nov 25 '14 at 08:18
  • 1
    @alain.janinm I fail to see the similarities. The only thing that seems "close" with `StringUtils.containsIgnoreCase()` is that both my solution and the Apache one use a `regionMatches()` method (in a cycle), but even that is not the same as I call `String.regionMatches()` and Apache calls `CharSequenceUtils.regionMatches()`. – icza Nov 25 '14 at 08:32
  • 3
    @icza `CharSequenceUtils.regionMatches` just calls `String.regionMatches` actually. Anyway, my point was to give the info, that if someone is already using StringUtils lib he can just call it because it seems to be an efficient way like you prove it with you benchmark. If I was not using Apache lib, I would definitively use your method ;) – alain.janinm Nov 25 '14 at 11:19
  • Clever. Is there any particular performance reason why you start searching at the end of `src` for `what` ? It seems that the most common use case for this function is with a search filter, and in that case the odds are that `what` will be at the beginning of `src`. – Martin Devillers Aug 05 '15 at 15:28
  • @MartinDevillers I start searching at the end so the loop can go downward. And I go downward because that way the condition of the loop will be shorter and more efficient (comparing to 0), and also so that no temp variable is required to store the end/last position. – icza Aug 05 '15 at 15:52
  • OK thanks for you answer! I'm not entirely convinced that these benefits outweigh the drawbacks I mentioned, but at least it's clear. – Martin Devillers Aug 05 '15 at 22:07
  • I would bet that a significant part of your speedup is the single character test. But if you're going to take the time and effort for that speedup, you should just use Boyer–Moore instead – Greg Dougherty May 18 '16 at 18:34
  • You should try comparing moving up vs moving down. I suspect the performance consideration Martin brought up is more significant than comparing against zero. I tend to write for-loops initializing two variables,`i`, starting from `0` and moving up, and `n`, set to the maximum value, so it's held locally and not repeatedly fetched or computed from wherever. Contains most of the same performance benefits of starting at max and moving down to `0`... your stack is a few bytes longer for that one extra local variable is all. – ArtOfWarfare Apr 11 '17 at 15:02
  • Very thorough. My take-away would be that they are all within a reasonable range of each other except for the un-compiled regex, so whichever method you find easiest to remember and implement at the time is good enough, but avoid a standard regex, and that there is a fast solution if you identify this as a performance bottleneck. – Bill K Dec 07 '17 at 18:56
  • In my tests it one was slow, very slow to compare on list interation on `Android` using a `SearchView` with `Filter` implementation on my `Adapter` – Abner Escócio Jul 26 '18 at 14:28
  • 2
    @icza can you add the apache StringUtils.containsIngnoreCase in your test case? I think it's easier for people here to understand yours is faster. – Rafael Sanches May 16 '19 at 21:29
  • How is this better than the one line of code that OP mentioned where you convert both strings to lower case before comparing? – Mugen Apr 16 '20 at 06:30
  • 1
    @Mugen This solution does not convert the strings to lower case. – icza Apr 16 '20 at 07:41
  • Apache Commons `org.apache.commons.lang3.StringUtils.containsIgnoreCase("AbBaCca", "bac");` uses this offering easy to use solution. https://stackoverflow.com/a/9560307/7878602 – ImtiazeA Aug 03 '21 at 05:44
40

A simpler way of doing this (without worrying about pattern matching) would be converting both Strings to lowercase:

String foobar = "fooBar";
String bar = "FOO";
if (foobar.toLowerCase().contains(bar.toLowerCase()) {
    System.out.println("It's a match!");
}
Phil
  • 35,852
  • 23
  • 123
  • 164
  • 5
    Character case is language dependent, which means it will work on your computer but will fail for the customer :). see @Adriaan Koster comment. – kroiz Jul 22 '12 at 06:26
  • 1
    @kroiz, that depends where the String came from. Comparing "foobar" and "FOO" will always match, however if you are comparing user-input information, or language-specific content, then you are right - a developer should be cautious. – Phil Jul 23 '12 at 13:28
  • 1
    Uppercase is actually a slightly better transform for this comparison with other languages (recommended by Microsoft for example) – Jared G Nov 03 '21 at 16:20
20

Yes, this is achievable:

String s1 = "abBaCca";
String s2 = "bac";

String s1Lower = s1;

// Keep s1 intact for print purposes, if needed.
s1Lower = s1Lower.toLowerCase();

String trueStatement = "FALSE!";
if (s1Lower.contains(s2)) {
    return "TRUE!"
}

return trueStatement;

This code will return the String "TRUE!", as it found that your characters were contained.

Ola Ström
  • 4,136
  • 5
  • 22
  • 41
Bilbo Baggins
  • 257
  • 2
  • 2
  • 13
    A big drawback of using toLowerCase() is that the outcome depends on the current Locale. See: http://javapapers.com/core-java/javas-tolowercase-has-got-a-surprise-for-you/ – Adriaan Koster Apr 21 '11 at 13:41
  • 4
    The question actually contains a better solution as this one fails for non-lowercase `s2`. Not speaking about such details like that this one doesn't compile and if it did, it'd return a string. – maaartinus Oct 03 '14 at 14:19
8

You can use regular expressions, and it works:

boolean found = s1.matches("(?i).*" + s2+ ".*");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shiv
  • 1,269
  • 11
  • 20
4

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();
}
Hakanai
  • 12,010
  • 10
  • 62
  • 132
3

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jan Newmarch
  • 361
  • 2
  • 5
  • Good that you put timing results. Everyone says how slow regex is, but in reality it's very fast if you only have to compile the regex once. – woot Feb 18 '17 at 16:35
3

There is a simple concise way, using regex flag (case insensitive {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)
 * */
Mr.Q
  • 4,316
  • 3
  • 43
  • 40
2
"AbCd".toLowerCase().contains("abcD".toLowerCase())
Ataur Rahman Munna
  • 3,887
  • 1
  • 23
  • 34
  • 2
    Can you improve your answer by explaining how your code resolves the problem? – Izuka Dec 13 '17 at 07:58
  • 2
    This answer has already been suggested in many of the other, more detailed answers to this question that others have provided. I don't think this answer serves any purpose here. – DaveyDaveDave Dec 13 '17 at 08:01
1

I'm not sure what your main question is here, but yes, .contains is case sensitive.

SCdF
  • 57,260
  • 24
  • 77
  • 113
0
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
seth
  • 1
  • 1
0

If you have to search an ASCII string in another ASCII string, such as a URL, you will find my solution to be better. I've tested icza's method and mine for the speed and here are the results:

  • Case 1 took 2788 ms - regionMatches
  • Case 2 took 1520 ms - my

The code:

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));
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Revertron
  • 1,213
  • 2
  • 13
  • 17
0
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");
        }

    }

}
Stéphane GRILLON
  • 11,140
  • 10
  • 85
  • 154
  • Thank you for this code snippet, which might provide some limited short-term help. A proper explanation [would greatly improve](//meta.stackexchange.com/q/114762) its long-term value by showing *why* this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – Toby Speight Feb 20 '18 at 09:20
0

or you can use a simple approach and just convert the string's case to substring's case and then use contains method.

0

Quick workaround :

if (yourstring.toLowerCase().contains("your string lower case")){

}
Ashraf Amin
  • 343
  • 3
  • 7
-1
String x="abCd";
System.out.println(Pattern.compile("c",Pattern.CASE_INSENSITIVE).matcher(x).find());
Jainendra
  • 24,713
  • 30
  • 122
  • 169
IVY
  • 1
-1

We can use stream with anyMatch and contains of Java 8

public class Test2 {
    public static void main(String[] args) {

        String a = "Gina Gini Protijayi Soudipta";
        String b = "Gini";

        System.out.println(WordPresentOrNot(a, b));
    }// main

    private static boolean WordPresentOrNot(String a, String b) {
    //contains is case sensitive. That's why change it to upper or lower case. Then check
        // Here we are using stream with anyMatch
        boolean match = Arrays.stream(a.toLowerCase().split(" ")).anyMatch(b.toLowerCase()::contains);
        return match;
    }

}
Soudipta Dutta
  • 1,353
  • 1
  • 12
  • 7
-2

You could simply do something like this:

String s1 = "AbBaCca";
String s2 = "bac";
String toLower = s1.toLowerCase();
return toLower.contains(s2);
Tunaki
  • 132,869
  • 46
  • 340
  • 423