题
indexOf(String) 方法区分大小写吗?如果是这样,是否有不区分大小写的版本?
解决方案
在indexOf()
方法都是区分大小写。你可以让他们(大致,在一个破碎的方式,但对于很多案件工作)不区分大小写事先通过转换您的字符串/小写:
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前两个字符串转换为小写:
@Test
public void caseInsensitiveIndexOf() {
assertTrue("Hello World!".toLowerCase().indexOf("Hello".toLowerCase()) != -1);
assertTrue("Hello World!".toLowerCase().indexOf("hello".toLowerCase()) != -1);
}
有在StringUtils类Apache的百科全书Lang库的忽略大小写方法
indexOfIgnoreCase(STR的CharSequence,CharSequence的字符串searchstr)
是,indexOf
是大小写敏感的。
做的情况下insensivity我已经发现最好的办法是:
String original;
int idx = original.toLowerCase().indexOf(someStr.toLowerCase());
这会做区分大小写indexOf()
。
下面是我的解决方案,其不分配任何堆内存,因此它应该比大多数这里提到的其它实施方式的显著更快。
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));
}
是,它是大小写敏感的。您可以通过搜索之前,你的字符串和字符串参数都转换为大写做不区分大小写的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,这是正确的。什么导致问题是THA toUpperCase()中的“SS”字符转换成两个字符,“SS”,这将引发的索引关
因此,总是与toLowerCase()粘
你拿一次返回的指标值在干什么?
如果您正在使用它来操纵你的字符串,那么你能不能使用正则表达式呢?
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") );
}
是的,我相当肯定它是。工作周围使用标准库将是一个方法:
int index = str.toUpperCase().indexOf("FOO");
有同样的问题。 我想正则表达式和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;
}
根据我的测试,它的速度更快......(至少,如果你的搜索字符串很短)。 如果您有任何改进和bug的任何建议,这将是很好,让我知道...(因为我在应用程序中使用此代码; - )
第一个问题已经回答过很多次了。是的 String.indexOf()
方法均区分大小写。
如果您需要区域设置敏感的 indexOf()
你可以使用 校订者. 。根据您设置的强度值,您可以获得不区分大小写的比较,并将重音字母与非重音字母视为相同,等等。以下是如何执行此操作的示例:
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;
}
总结一下,3个解决方案:
- 使用 toLowerCase() 或 toUpperCase
- 使用apache的StringUtils
- 使用正则表达式
现在,我想知道哪一个最快?我猜平均第一个。
但它并不难写一个:
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());
}
}
转换两个字符串为小写通常不是什么大不了的事,但是这将是缓慢的,如果某些字符串长。如果你这样做在一个循环中那么这将是非常糟糕的。出于这个原因,我建议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;
}
}
这里的一个版本非常类似于Apache的StringUtils的版本:
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是大小写敏感的。这是因为它使用了equals方法在列表中的元素进行比较。同样的事情会为包含和除去。