Frage

Ist das indexOf (String) -Methode Groß- und Kleinschreibung? Wenn ja, gibt es einen Fall unempfindliche Version davon?

War es hilfreich?

Lösung

Die indexOf() Methoden sind alle case-sensitive. Sie können sie machen (etwa, in einem gebrochenen Weg, aber die Arbeit für viele Fälle) Groß- und Kleinschreibung durch die Saiten auf Groß- / Kleinschreibung Umwandlung vorher:

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

Andere Tipps

  

Ist das indexOf (String) -Methode Groß- und Kleinschreibung?

Ja, es ist Groß- und Kleinschreibung:

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

Wenn ja, gibt es einen Fall unempfindliche Version davon?

Nein, gibt es nicht. Sie können beide Strings in Kleinbuchstaben umwandeln, bevor indexOf Aufruf:

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

Es gibt einen Fall Verfahren in StringUtils Klasse der Bibliothek Apache Commons Lang ignorieren

indexOfIgnoreCase (CharSequence str, CharSequence searchStr)

Ja, das ist indexOf Groß- und Kleinschreibung.

Der beste Weg Fall Unempfindlichkeit zu tun, die ich gefunden habe ist:

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

Das wird ein Groß- und Kleinschreibung indexOf() tun.

Hier ist meine Lösung, die keinen Heap-Speicher nicht vor, doch sollte daher deutlich schneller als die meisten anderen Implementierungen hier erwähnt werden.

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

Und hier sind die Unit-Tests, die das richtige Verhalten überprüfen.

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

Ja, es wird zwischen Groß- und Kleinschreibung unterschieden. Sie können sowohl durch das Umwandeln Ihres String und die String-Parameter ein Groß- und Kleinschreibung indexOf tun in Großbuchstaben vor der Suche.

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

Beachten Sie, dass toUpperCase unter bestimmten Umständen nicht funktionieren. Zum Beispiel dieses:

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

idxU wird 20 sein, was falsch ist! idxL wird 19 sein, was richtig ist. Was verursacht das Problem ist tha toUpperCase (), um den „ß“ Charakter in zwei Zeichen umwandelt, „SS“ und dies führt den Index aus.

Folglich immer Stick mit toLowerCase ()

Was Sie mit dem Indexwert zu tun einmal zurück?

Wenn Sie es verwenden, um Ihre Zeichenfolge zu manipulieren, dann könnte man nicht stattdessen einen regulären Ausdruck verwenden?

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

Ich habe gerade an der Quelle sieht. Er vergleicht Zeichen, so dass es Groß- und Kleinschreibung ist.

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

Ja, ich bin ziemlich sicher, dass es ist. Ein Verfahren zur Umgehung, dass die Standard-Bibliothek unter Verwendung wäre:

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

das gleiche Problem hat. Ich habe versucht, reguläre Ausdrücke und die Apache StringUtils.indexOfIgnoreCase-Methode, aber beide waren ziemlich langsam ... Also schrieb ich eine kurze Methode mich ...:

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

Nach meinen Tests seines viel schneller ... (zumindest, wenn Ihr searchString- ist ziemlich kurz). wenn Sie irgendwelche Verbesserungsvorschläge oder Fehler haben wäre es schön, mich wissen zu lassen ... (da ich diesen Code in einer Anwendung verwenden; -)

Die erste Frage ist bereits mehrfach beantwortet. Ja, die String.indexOf() Methoden sind alle case-sensitive.

Wenn Sie eine locale-sensitive indexOf() benötigen könnten Sie die

Nur um es zusammenzufassen, 3 Lösungen:

  • mit toLowerCase () oder toUpperCase
  • mit StringUtils von Apache
  • mit regex

Nun, was ich habe mich gefragt, war Welches ist der schnellste? Ich schätze, dass im Durchschnitt der ersten.

Aber es ist nicht schwer zu schreiben:

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

beiden Strings Konvertieren zu Fall zu senken, ist in der Regel keine große Sache, aber es wäre langsam sein, wenn einige der Saiten lang ist. Und wenn Sie dies in einer Schleife zu tun, dann wäre es wirklich schlecht. Aus diesem Grunde würde ich indexOfIgnoreCase empfehlen.

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

        }

Hier ist eine Version sehr ähnlich Apache 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 ist Groß- und Kleinschreibung. Dies ist, weil es die equals-Methode verwendet, die Elemente in der Liste zu vergleichen. Das gleiche gilt für enthält und entfernen.

scroll top