indexOf(String)方法是否区分大小写?如果是,是否有不区分大小写的版本?
indexOf(String)方法是否区分大小写?如果是,是否有不区分大小写的版本?
indexOf()
方法都是区分大小写的。你可以通过在使用该方法之前将字符串转换为大写/小写来使它们(粗略地、以一种有缺陷但对许多情况有效的方式)不区分大小写:
s1 = s1.toLowerCase(Locale.US);
s2 = s2.toLowerCase(Locale.US);
s1.indexOf(s2);
"ß".toUpperCase().equals("SS")
。 - SimonindexOf(String)方法区分大小写。
是的,它区分大小写:
@Test
public void indexOfIsCaseSensitive() {
assertTrue("Hello World!".indexOf("Hello") != -1);
assertTrue("Hello World!".indexOf("hello") == -1);
}
如果需要,是否有一个不区分大小写的版本呢?
没有。但是您可以在调用indexOf之前将两个字符串转换为小写字母:
@Test
public void caseInsensitiveIndexOf() {
assertTrue("Hello World!".toLowerCase().indexOf("Hello".toLowerCase()) != -1);
assertTrue("Hello World!".toLowerCase().indexOf("hello".toLowerCase()) != -1);
}
"ı".toLowerCase(Locale.US).indexOf("I".toLowerCase(Locale.US))
应该返回0,因为第一个字符串是土耳其小写字母"I",所以应当与第二个字符串中的大写字母"I"比较相等,但实际上返回-1,因为后者被转换成了 "i")。 - JulesApache Commons Lang库中的StringUtils类有一个忽略大小写的方法
indexOfIgnoreCase(CharSequence str, CharSequence searchStr)
这是我的解决方案,它不会分配任何堆内存,因此应该比这里提到的大多数其他实现方法都快得多。
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;
}
这里是验证正确行为的单元测试。
@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));
}
assertThat(StringUtils.indexOfIgnoreCase("ı" /* 土耳其小写字母 I,U+0131 */, "I"), is(0));
- Jules是的,indexOf
是区分大小写的。
我发现实现大小写不敏感的最好方法是:
String original;
int idx = original.toLowerCase().indexOf(someStr.toLowerCase());
这将执行不区分大小写的 indexOf()
操作。
original.toLowerCase().length()
并不总是等于original.length()
。结果idx
不能正确地映射回original
。 - Cheok Yan Cheng是的,它区分大小写。您可以通过在搜索之前将您的字符串和字符串参数都转换为大写来执行不区分大小写的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",导致索引失误。
因此,建议始终使用 toLowerCase()。
find
改为 "STRASSE"
,它在小写变体中根本找不到,但在大写版本中可以正确地找到。 - Jules一旦返回索引值,您将如何使用它?
如果您要使用它来操作字符串,那么是否可以使用正则表达式代替?
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);
}
}
@Test
public void testIndexofCaseSensitive() {
TestCase.assertEquals(-1, "abcDef".indexOf("d") );
}
我曾遇到相同的问题。我尝试了正则表达式和 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;
}
indexOfIgnoreCase(“İ”,“i”)
应返回0,因为İ
是土耳其文本中i
的正确大写形式,但实际上返回-1,因为i
被大写为更常见的I
)。 - Jules是的,我相当确定。使用标准库解决这个问题的一种方法是:
int index = str.toUpperCase().indexOf("FOO");