code

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

codestyles 2020. 11. 13. 08:14
반응형

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

방금 출처를 살펴 보았습니다. 문자를 비교하므로 대소 문자를 구분합니다.


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

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

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

같은 문제가있었습니다. 정규식과 아파치 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()방법은 모두 대소 문자를 구분합니다.

If you need a locale-sensitive indexOf() you could use the Collator. Depending on the strength value you set you can get case insensitive comparison, and also treat accented letters as the same as the non-accented ones, etc. Here is an example of how to do this:

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

Just to sum it up, 3 solutions:

  • using toLowerCase() or toUpperCase
  • using StringUtils of apache
  • using regex

Now, what I was wondering was which one is the fastest? I'm guessing on average the first one.


But it's not hard to write one:

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

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.


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

        }

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

indexOf is case sensitive. This is because it uses the equals method to compare the elements in the list. The same thing goes for contains and remove.

참고URL : https://stackoverflow.com/questions/1126227/indexof-case-sensitive

반응형