indexOf区分大小写?
indexOf(String)方法是否区分大小写? 如果是这样,那么它是否有一个不区分大小写的版本?
indexOf()
方法都是区分大小写的。 你可以把它们做成粗略的(粗略地说,以一种破碎的方式,但是对大量的情况来说)不区分大小写,方法是先把你的string转换成大写/小写字母:
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之前,可以将这两个string转换为小写字母:
@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()
。
是的,这是区分大小写的。 在search之前,您可以通过将您的string和string参数都转换为大写来执行不区分大小写的indexOf
。
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”,这将引发索引closures。
因此,总是坚持toLowerCase()
这是我的解决scheme,不分配任何堆内存,因此它应该比这里提到的大多数其他实现快得多。
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; }
这里是validation正确行为的unit testing。
@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)); }
@Test public void testIndexofCaseSensitive() { TestCase.assertEquals(-1, "abcDef".indexOf("d") ); }
我刚才看了一下源代码 它比较字符,因此区分大小写。
是的,我相当肯定这是。 解决使用标准库的一种方法是:
int index = str.toUpperCase().indexOf("FOO");
有同样的问题。 我尝试了正则expression式和Apache的StringUtils.indexOfIgnoreCase方法,但都很慢…所以我写了一个简短的方法我自己…:
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; }
根据我的testing它快得多…(至less如果你的searchString是相当短的)。 如果你有任何改进或错误的build议,这将是很高兴让我知道…(因为我在应用程序中使用此代码;-)
总结一下,3个解决scheme:
- 使用toLowerCase()或toUpperCase
- 使用apache的StringUtils
- 使用正则expression式
现在,我想知道哪一个是最快的? 我平均猜测第一个。
但是写一个不难:
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()); } }
你一旦返回索引值,你在做什么?
如果您正在使用它来操纵您的string,那么您是否可以不使用正则expression式呢?
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); } }
将这两个string转换为小写字母通常不是什么大问题,但是如果某些string很长,则会很慢。 如果你在循环中这样做,那将是非常糟糕的。 出于这个原因,我会build议indexOfIgnoreCase
。
第一个问题已经被多次回答了。 是的, String.indexOf()
方法都是区分大小写的。
如果你需要一个语言环境敏感的indexOf()
你可以使用Collator 。 根据你设定的强度值,你可以得到不区分大小写的比较,也可以把重音字母看作和非重音字母一样,下面是一个如何做到这一点的例子:
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; }
indexOf区分大小写。 这是因为它使用equals方法来比较列表中的元素。 同样的事情包含和删除。