Question

La méthode indexOf (String) sensible à la casse? Si oui, est-il un cas la version insensible de celui-ci?

Était-ce utile?

La solution

Les méthodes de indexOf() sont tous sensibles à la casse. Vous pouvez les faire (à peu près, d'une manière brisée, mais travaillant pour beaucoup de cas) insensible à la casse en convertissant vos chaînes en majuscules / minuscules préalable:

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

Autres conseils

  

est le cas de la méthode indexOf (String) sensible?

Oui, il est sensible à la casse:

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

Si oui, est-il un cas la version insensible de celui-ci?

Non, il n'y a pas. Vous pouvez convertir les chaînes en minuscules avant d'appeler indexOf:

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

Il y a une méthode ignorer de cas en classe StringUtils de la bibliothèque Apache Commons Lang

indexOfIgnoreCase (CharSequence str, CharSequence searchStr)

Oui, indexOf est sensible à la casse.

La meilleure façon de le faire le cas que j'ai trouvé l'insensibilité est:

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

Cela ne insensible à la casse indexOf().

Voici ma solution qui n'alloue pas de mémoire de tas, donc il devrait être nettement plus rapide que la plupart des autres implémentations mentionnées ici.

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

Et voici les tests unitaires qui permettent de vérifier le comportement correct.

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

Oui, il est sensible à la casse. Vous pouvez faire un indexOf insensible à la casse en convertissant votre chaîne et le paramètre de chaîne aussi bien en majuscules avant la recherche.

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

Notez que toUpperCase peut ne pas fonctionner dans certaines circonstances. Par exemple ceci:

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

idxU sera 20, ce qui est faux! idxL sera 19, ce qui est correct. Ce qui est à l'origine du problème est tha toUpperCase () convertit le caractère « ß » en deux caractères, « SS » et cela jette l'indice hors tension.

Par conséquent, toujours tenir à toLowerCase ()

Que faites-vous avec la valeur d'index une fois de retour?

Si vous utilisez pour manipuler votre chaîne, pourriez-vous pas utiliser à la place une expression régulière?

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

Je l'ai juste regardé la source. Il compare les caractères de sorte qu'il est sensible à la casse.

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

Oui, je suis assez sûr qu'il est. Une méthode de travail autour que l'utilisation de la bibliothèque standard serait:

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

eu le même problème. J'ai essayé expression régulière et la méthode StringUtils.indexOfIgnoreCase apache, mais les deux étaient assez lent ... Alors, je l'ai écrit moi-même une méthode courte ...:

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

D'après mes tests le plus rapide ... (au moins si votre searchString est assez court). si vous avez des suggestions d'amélioration ou de bugs, il serait bien de me le faire savoir ... (puisque j'utilise ce code dans une application; -)

La première question a déjà répondu à plusieurs reprises. Oui, les méthodes de String.indexOf() sont tous sensibles à la casse.

Si vous avez besoin d'un indexOf() de paramètres régionaux, vous pouvez utiliser le

Juste pour résumer, 3 solutions:

  • en utilisant toLowerCase () ou toUpperCase
  • à l'aide de StringUtils apache
  • à l'aide regex

Maintenant, ce que je me demandais était que l'on est le plus rapide? Je devine en moyenne la première.

Mais ce n'est pas difficile d'écrire un:

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

Conversion les deux chaînes à minuscules est généralement pas une grosse affaire, mais il serait lent si certains des cordes est longue. Et si vous faites cela dans une boucle alors il serait vraiment mauvais. Pour cette raison, je recommanderais 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;
            }

        }

Voici une version ressemblant étroitement à la version StringUtils Apache:

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 est sensible à la casse. En effet, il utilise la méthode equals pour comparer les éléments de la liste. La même chose vaut pour contient et supprimer.

scroll top