indexOf Case Sensitive?

后端 未结 19 1158
日久生厌
日久生厌 2020-11-27 19:39

Is the indexOf(String) method case sensitive? If so, is there a case insensitive version of it?

相关标签:
19条回答
  • 2020-11-27 19:58

    Converting both strings to lower-case is usually not a big deal but it would be slow if some of the strings is long. And if you do this in a loop then it would be really bad. For this reason, I would recommend indexOfIgnoreCase.

    0 讨论(0)
  • 2020-11-27 20:00

    The indexOf() methods are all case-sensitive. You can make them (roughly, in a broken way, but working for plenty of cases) case-insensitive by converting your strings to upper/lower case beforehand:

    s1 = s1.toLowerCase(Locale.US);
    s2 = s2.toLowerCase(Locale.US);
    s1.indexOf(s2);
    
    0 讨论(0)
  • 2020-11-27 20:00

    There is an ignore case method in StringUtils class of Apache Commons Lang library

    indexOfIgnoreCase(CharSequence str, CharSequence searchStr)

    0 讨论(0)
  • 2020-11-27 20:00

    Here is my solution which does not allocate any heap memory, therefore it should be significantly faster than most of the other implementations mentioned here.

    public static int indexOfIgnoreCase(final String haystack,
                                        final String needle) {
        if (needle.isEmpty() || haystack.isEmpty()) {
            // Fallback to legacy behavior.
            return haystack.indexOf(needle);
        }
    
        for (int i = 0; i < haystack.length(); ++i) {
            // Early out, if possible.
            if (i + needle.length() > haystack.length()) {
                return -1;
            }
    
            // Attempt to match substring starting at position i of haystack.
            int j = 0;
            int ii = i;
            while (ii < haystack.length() && j < needle.length()) {
                char c = Character.toLowerCase(haystack.charAt(ii));
                char c2 = Character.toLowerCase(needle.charAt(j));
                if (c != c2) {
                    break;
                }
                j++;
                ii++;
            }
            // Walked all the way to the end of the needle, return the start
            // position that this was found.
            if (j == needle.length()) {
                return i;
            }
        }
    
        return -1;
    }
    

    And here are the unit tests that verify correct behavior.

    @Test
    public void testIndexOfIgnoreCase() {
        assertThat(StringUtils.indexOfIgnoreCase("A", "A"), is(0));
        assertThat(StringUtils.indexOfIgnoreCase("a", "A"), is(0));
        assertThat(StringUtils.indexOfIgnoreCase("A", "a"), is(0));
        assertThat(StringUtils.indexOfIgnoreCase("a", "a"), is(0));
    
        assertThat(StringUtils.indexOfIgnoreCase("a", "ba"), is(-1));
        assertThat(StringUtils.indexOfIgnoreCase("ba", "a"), is(1));
    
        assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", " Royal Blue"), is(-1));
        assertThat(StringUtils.indexOfIgnoreCase(" Royal Blue", "Royal Blue"), is(1));
        assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "royal"), is(0));
        assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "oyal"), is(1));
        assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "al"), is(3));
        assertThat(StringUtils.indexOfIgnoreCase("", "royal"), is(-1));
        assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", ""), is(0));
        assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "BLUE"), is(6));
        assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "BIGLONGSTRING"), is(-1));
        assertThat(StringUtils.indexOfIgnoreCase("Royal Blue", "Royal Blue LONGSTRING"), is(-1));  
    }
    
    0 讨论(0)
  • 2020-11-27 20:00

    I've just looked at the source. It compares chars so it is case sensitive.

    0 讨论(0)
  • 2020-11-27 20:02

    Here's a version closely resembling Apache's StringUtils version:

    public int indexOfIgnoreCase(String str, String searchStr) {
        return indexOfIgnoreCase(str, searchStr, 0);
    }
    
    public int indexOfIgnoreCase(String str, String searchStr, int fromIndex) {
        // https://stackoverflow.com/questions/14018478/string-contains-ignore-case/14018511
        if(str == null || searchStr == null) return -1;
        if (searchStr.length() == 0) return fromIndex;  // empty string found; use same behavior as Apache StringUtils
        final int endLimit = str.length() - searchStr.length() + 1;
        for (int i = fromIndex; i < endLimit; i++) {
            if (str.regionMatches(true, i, searchStr, 0, searchStr.length())) return i;
        }
        return -1;
    }
    
    0 讨论(0)
提交回复
热议问题