indexOf区分大小写?

Bri*_*ian 67 java case-sensitive

indexOf(String)方法区分大小写吗?如果是这样,它是否有不区分大小写的版本?

Joe*_*oey 64

这些indexOf()方法都是区分大小写的.您可以通过事先将字符串转换为大写/小写来制作它们(粗略地,以一种破碎的方式,但适用于大量情况)不区分大小写:

s1 = s1.toLowerCase(Locale.US);
s2 = s2.toLowerCase(Locale.US);
s1.indexOf(s2);
Run Code Online (Sandbox Code Playgroud)

  • 不行.转换为大写/小写时,一些奇怪的国际字符会转换为多个字符.例如:`"ß".toUpperCase().equals("SS")` (5认同)
  • 使用toUpperCase时要注意国际化问题(即土耳其语).更合适的解决方案是使用str.toUpperCase(Locale.US).indexOf(...); (3认同)
  • 根据Unicode比较规则,我很确定案例转换然后比较并不完全正确.它适用于某些事情(即案例折叠,通常仅在语法分析上下文中使用)但是对于自然语言,可能存在这样的特殊情况,其中两个应该比较相等的字符串不是大写或两个小写.然而,我无法想出任何关于蝙蝠的例子. (2认同)

dfa*_*dfa 39

indexOf(String)方法区分大小写吗?

是的,它区分大小写:

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

如果是这样,它是否有不区分大小写的版本?

不,没有.在调用indexOf之前,您可以将两个字符串转换为小写:

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

  • 哦,请不要忘记使用Locale.US进行文化不变转换,我们在土耳其语语言环境下运行的java应用程序遇到了足够的问题. (8认同)

小智 19

Apache Commons Lang库的StringUtils类中有一个ignore case方法

indexOfIgnoreCase(CharSequence str,CharSequence searchStr)


jjn*_*guy 16

是的,indexOf区分大小写.

我发现不区分大小写的最佳方法是:

String original;
int idx = original.toLowerCase().indexOf(someStr.toLowerCase());
Run Code Online (Sandbox Code Playgroud)

这样做会不区分大小写indexOf().

  • 不,永远不要那样做。原因是,`original.toLowerCase().length()` 并不总是等于`original.length()`。结果 `idx` 无法正确映射回 `original`。 (2认同)

Zac*_*ies 11

这是我的解决方案,它不分配任何堆内存,因此它应该比这里提到的大多数其他实现快得多.

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;
}
Run Code Online (Sandbox Code Playgroud)

以下是验证正确行为的单元测试.

@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));  
}
Run Code Online (Sandbox Code Playgroud)

  • 答案是"不,没有不区分大小写的indexOf版本".但是,我在这里添加了解决方案,因为人们会找到这个寻找解决方案的页面.我使用测试用例提供了我的解决方案,以便下一个人可以使用我的代码来解决完全相同的问题.这就是为什么堆栈溢出是有用的呢?我有十年编写高性能代码的经验,其中一半是谷歌.我只是免费提供了一个经过良好测试的解决方案来帮助社区. (4认同)
  • 这正是我感兴趣的.我发现这比Apache Commons版本快10-15%.如果我可以多次投票,我会.谢谢! (2认同)
  • 这是一个缺少的测试用例:`assertThat(StringUtils.indexOfIgnoreCase("ı"/*土耳其小写I,U + 0131*/,"I"),是(0)); (2认同)

Nic*_*wis 10

是的,它区分大小写.您可以indexOf通过在搜索之前将String和String参数转换为大写来执行不区分大小写的操作.

String str = "Hello world";
String search = "hello";
str.toUpperCase().indexOf(search.toUpperCase());
Run Code Online (Sandbox Code Playgroud)

请注意,在某些情况下,toUpperCase可能无法正常工作.例如:

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

idxU将是20,这是错误的!idxL将是19,这是正确的.导致问题的原因是toUpperCase()将"ß"字符转换为两个字符"SS",这会抛出索引.

因此,始终坚持使用toLowerCase()