Pregunta

es el indexOf (String) Caso método sensible? Si es así, ¿hay un caso insensible versión de la misma?

¿Fue útil?

Solución

Los métodos indexOf() son todas mayúsculas y minúsculas. Puede hacerlos (más o menos, de forma quebrada, pero trabajando para un montón de casos) entre mayúsculas y minúsculas mediante la conversión de sus cadenas a mayúsculas / minúsculas de antemano:

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

Otros consejos

  

es el indexOf (String) Caso método sensible?

Sí, es sensible a mayúsculas:

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

Si es así, ¿hay un caso insensible versión de la misma?

No, no lo hay. Usted puede convertir cadenas a minúsculas antes de llamar a indexOf:

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

Hay un método de casos ignorar en la clase StringUtils de biblioteca Apache Commons Lang

indexOfIgnoreCase (CharSequence str, CharSequence searchStr)

Sí, indexOf entre mayúsculas y minúsculas.

La mejor manera de hacerlo insensibilidad caso he encontrado es:

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

Con eso basta un caso indexOf() insensibles.

Aquí está mi solución que no asigna ninguna memoria del montón, por lo tanto, debe ser significativamente más rápido que la mayoría de las otras implementaciones mencionadas aquí.

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

Y aquí están las pruebas de unidad que verifican el comportamiento correcto.

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

Sí, es entre mayúsculas y minúsculas. Usted puede hacer una indexOf entre mayúsculas y minúsculas mediante la conversión de la cadena y el parámetro de cadena tanto a mayúsculas antes de la búsqueda.

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

Tenga en cuenta que toUpperCase puede no funcionar en algunas circunstancias. Por ejemplo esto:

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

idxU habrá 20, que es un error! idxL será 19, que es correcto. Lo que está causando el problema es tha toUpperCase () convierte el carácter "ß" en dos personajes, "SS" y esto arroja el índice fuera.

En consecuencia, siempre se mantienen con toLowerCase ()

¿Qué haces con el valor del índice una vez devuelta?

Si lo está utilizando para manipular su cadena, entonces se puede no utilizar una expresión regular en su lugar?

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

He miraba a la fuente. Se comparan caracteres de modo que es sensible a mayúsculas.

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

Sí, estoy bastante seguro de que es. Un método de trabajo en torno a que el uso de la biblioteca estándar sería:

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

tenía el mismo problema. Probé expresión regular y el Apache StringUtils.indexOfIgnoreCase-Método, pero ambos eran bastante lento ... Así que escribí un método corto a mí mismo ...:

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

Según mis pruebas es mucho más rápido ... (al menos si su searchString que es más bien corto). si usted tiene alguna sugerencia de mejora o insectos que sería bueno que me permita saber ... (ya que utilizar este código en una aplicación; -)

La primera pregunta ya ha sido contestada muchas veces. Sí, los métodos String.indexOf() son todas mayúsculas y minúsculas.

Si necesita un indexOf() sensible a la localidad podría utilizar el Compaginadora. Dependiendo del valor de la fuerza de configurar puede obtener caso la comparación insensible, y también el tratamiento de las letras acentuadas como los mismos que los que no acentuadas, etc. Aquí está un ejemplo de cómo hacer esto:

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

Sólo para resumir, 3 soluciones:

  • usando toLowerCase () o toUpperCase
  • usando StringUtils de Apache
  • usando expresiones regulares

Ahora, lo que preguntaba era cuál es el más rápido? Supongo que, en promedio, la primera de ellas.

Pero no es difícil escribir una:

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

La conversión de ambas cadenas a minúsculas por lo general no es un gran problema pero sería lento si algunas de las cadenas es larga. Y si lo hace en un bucle, entonces sería muy malo. Por esta razón, recomiendo 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;
            }

        }

Aquí hay una versión muy parecida a la versión StringUtils de 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 mayúsculas y minúsculas. Esto es debido a que utiliza el método equals para comparar los elementos de la lista. Lo mismo vale para los contiene y quitar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top