문제

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

StringUtils 클래스 Apache Commons Lang Library에는 무시 사례 방법이 있습니다.

indexofignoreCase (charSevence 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 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 세가 맞습니다. 문제를 일으키는 것은 Tha 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);
    }
}

방금 소스를 보았습니다. 그것은 숯을 비교하여 사례에 민감합니다.

@Test
public void testIndexofCaseSensitive() {
    TestCase.assertEquals(-1, "abcDef".indexOf("d") );
}

예, 나는 그것이 상당히 확신합니다. 표준 라이브러리를 사용하여 해결하는 한 가지 방법은 다음과 같습니다.

int index = str.toUpperCase().indexOf("FOO"); 

같은 문제가있었습니다. 나는 정규 표현과 Apache StringUtils.indexofignorecase-method를 시도했지만 둘 다 꽤 느 렸습니다 ... 그래서 나는 짧은 방법을 직접 썼습니다 ... :

public static int indexOfIgnoreCase(final String chkstr, final String searchStr, int i) {
    if (chkstr != null && searchStr != null && i > -1) {
          int serchStrLength = searchStr.length();
          char[] searchCharLc = new char[serchStrLength];
          char[] searchCharUc = new char[serchStrLength];
          searchStr.toUpperCase().getChars(0, serchStrLength, searchCharUc, 0);
          searchStr.toLowerCase().getChars(0, serchStrLength, searchCharLc, 0);
          int j = 0;
          for (int checkStrLength = chkstr.length(); i < checkStrLength; i++) {
                char charAt = chkstr.charAt(i);
                if (charAt == searchCharLc[j] || charAt == searchCharUc[j]) {
                     if (++j == serchStrLength) {
                           return i - j + 1;
                     }
                } else { // faster than: else if (j != 0) {
                         i = i - j;
                         j = 0;
                    }
              }
        }
        return -1;
  }

내 테스트에 따르면 훨씬 더 빠릅니다 ... (적어도 searchString이 다소 짧은 경우). 개선 또는 버그에 대한 제안이 있다면 알려 주시면 좋을 것입니다 ... (응용 프로그램 에서이 코드를 사용하기 때문에 ;-)

첫 번째 질문은 이미 여러 번 답변되었습니다.예, String.indexOf() 메소드는 모두 대소문자를 구분합니다.

로케일 구분이 필요한 경우 indexOf() 당신은 사용할 수 있습니다 대조자.설정한 강도 값에 따라 대소문자를 구분하지 않고 비교할 수 있으며 악센트가 있는 문자를 악센트가 없는 문자와 동일하게 처리할 수도 있습니다.이를 수행하는 방법의 예는 다음과 같습니다.

private int indexOf(String original, String search) {
    Collator collator = Collator.getInstance();
    collator.setStrength(Collator.PRIMARY);
    for (int i = 0; i <= original.length() - search.length(); i++) {
        if (collator.equals(search, original.substring(i, i + search.length()))) {
            return i;
        }
    }
    return -1;
}

요약하려면 3 가지 솔루션 :

  • TolowerCase () 또는 ToupperCase 사용
  • Apache의 StringUtils 사용
  • Regex 사용

자, 내가 궁금한 점은 어느 것이 가장 빠른지? 나는 평균적으로 첫 번째를 추측하고있다.

그러나 하나를 작성하는 것은 어렵지 않습니다.

public class CaseInsensitiveIndexOfTest extends TestCase {
    public void testOne() throws Exception {
        assertEquals(2, caseInsensitiveIndexOf("ABC", "xxabcdef"));
    }

    public static int caseInsensitiveIndexOf(String substring, String string) {
        return string.toLowerCase().indexOf(substring.toLowerCase());
    }
}

두 줄을 소문자로 변환하는 것은 일반적으로 큰 문제가 아니지만 일부 문자열이 길면 느리게됩니다. 그리고 당신이 루프에서 이것을한다면, 그것은 정말로 나쁠 것입니다. 이런 이유로, 나는 추천 할 것이다 indexOfIgnoreCase.

 static string Search(string factMessage, string b)
        {

            int index = factMessage.IndexOf(b, StringComparison.CurrentCultureIgnoreCase);
            string line = null;
            int i = index;
            if (i == -1)
            { return "not matched"; }
            else
            {
                while (factMessage[i] != ' ')
                {
                    line = line + factMessage[i];
                    i++;
                }

                return line;
            }

        }

다음은 Apache의 StringUtils 버전과 밀접하게 유사한 버전입니다.

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

indexof는 사례에 민감합니다. 이는 평등 메소드를 사용하여 목록의 요소를 비교하기 때문입니다. 포함 및 제거도 마찬가지입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top