[java] indexOf 대소 문자를 구분합니까?

indexOf (String) 메서드는 대소 문자를 구분합니까? 그렇다면 대소 문자를 구분하지 않는 버전이 있습니까?



답변

indexOf()방법은 모두 대소 문자를 구분합니다. 사전에 문자열을 대 / 소문자로 변환하여 대 / 소문자를 구분하지 않고 대소 문자를 구분하지 않도록 만들 수 있습니다.

s1 = s1.toLowerCase(Locale.US);
s2 = s2.toLowerCase(Locale.US);
s1.indexOf(s2);


답변

indexOf (String) 메서드는 대소 문자를 구분합니까?

예, 대소 문자를 구분합니다.

@Test
public void indexOfIsCaseSensitive() {
    assertTrue("Hello World!".indexOf("Hello") != -1);
    assertTrue("Hello World!".indexOf("hello") == -1);
}

그렇다면 대소 문자를 구분하지 않는 버전이 있습니까?

아니, 없습니다. indexOf를 호출하기 전에 두 문자열을 모두 소문자로 변환 할 수 있습니다.

@Test
public void caseInsensitiveIndexOf() {
    assertTrue("Hello World!".toLowerCase().indexOf("Hello".toLowerCase()) != -1);
    assertTrue("Hello World!".toLowerCase().indexOf("hello".toLowerCase()) != -1);
}


답변

Apache Commons Lang 라이브러리의 StringUtils 클래스에는 대소 문자 무시 메소드가 있습니다.

indexOfIgnoreCase (CharSequence str, CharSequence searchStr)


답변

예, indexOf대소 문자를 구분합니다.

내가 찾은 대소 문자 무감각을 수행하는 가장 좋은 방법은 다음과 같습니다.

String original;
int idx = original.toLowerCase().indexOf(someStr.toLowerCase());

대소 문자를 구분하지 않습니다 indexOf().


답변

여기에 힙 메모리를 할당하지 않는 솔루션이 있으므로 여기에 언급 된 대부분의 다른 구현보다 훨씬 빠릅니다.

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;
}

그리고 여기에 올바른 동작을 확인하는 단위 테스트가 있습니다.

@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));
}


답변

예, 대소 문자를 구분합니다. indexOf검색하기 전에 String 및 String 매개 변수를 모두 대문자로 변환하여 대소 문자를 구분하지 않을 수 있습니다 .

String str = "Hello world";
String search = "hello";
str.toUpperCase().indexOf(search.toUpperCase());

일부 상황에서는 toUpperCase가 작동하지 않을 수 있습니다. 예를 들면 다음과 같습니다.

String str = "Feldbergstraße 23, Mainz";
String find = "mainz";
int idxU = str.toUpperCase().indexOf (find.toUpperCase ());
int idxL = str.toLowerCase().indexOf (find.toLowerCase ());

idxU는 20이 될 것입니다. idxL은 19이며 맞습니다. 문제의 원인은 toUpperCase ()가 “ß”문자를 “SS”라는 두 문자로 변환하고 이로 인해 색인이 해제된다는 것입니다.

따라서 항상 toLowerCase ()를 고수하십시오.


답변

일단 반환 된 인덱스 값으로 무엇을하고 있습니까?

문자열을 조작하는 데 사용하는 경우 대신 정규식을 사용할 수 없습니까?

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class StringIndexOfRegexpTest {

    @Test
    public void testNastyIndexOfBasedReplace() {
        final String source = "Hello World";
        final int index = source.toLowerCase().indexOf("hello".toLowerCase());
        final String target = "Hi".concat(source.substring(index
                + "hello".length(), source.length()));
        assertEquals("Hi World", target);
    }

    @Test
    public void testSimpleRegexpBasedReplace() {
        final String source = "Hello World";
        final String target = source.replaceFirst("(?i)hello", "Hi");
        assertEquals("Hi World", target);
    }
}