В Java, как проверить, содержит ли строка подстроку (игнорируя регистр)?

У меня есть два String s, str1 и str2. Как проверить, содержится ли str2 в str1, игнорируя случай?

Ответ 1

str1.toLowerCase().contains(str2.toLowerCase())

Ответ 2

Как насчет matches()?

String string = "Madam, I am Adam";

// Starts with
boolean  b = string.startsWith("Mad");  // true

// Ends with
b = string.endsWith("dam");             // true

// Anywhere
b = string.indexOf("I am") >= 0;        // true

// To ignore case, regular expressions must be used

// Starts with
b = string.matches("(?i)mad.*");

// Ends with
b = string.matches("(?i).*adam");

// Anywhere
b = string.matches("(?i).*i am.*");

Ответ 3

Если вы можете использовать org.apache.commons.lang.StringUtils, я предлагаю использовать следующее:

String container = "aBcDeFg";
String content = "dE";
boolean containerContainsContent = StringUtils.containsIgnoreCase(container, content);

Ответ 4

Вы можете использовать метод toLowerCase():

public boolean contains( String haystack, String needle ) {
  haystack = haystack == null ? "" : haystack;
  needle = needle == null ? "" : needle;

  // Works, but is not the best.
  //return haystack.toLowerCase().indexOf( needle.toLowerCase() ) > -1

  return haystack.toLowerCase().contains( needle.toLowerCase() )
}

Затем вызовите его, используя:

if( contains( str1, str2 ) ) {
  System.out.println( "Found " + str2 + " within " + str1 + "." );
}

Обратите внимание, что, создав свой собственный метод, вы можете его повторно использовать. Затем, когда кто-то указывает, что вы должны использовать contains вместо indexOf, вы должны изменить только одну строку кода.

Ответ 5

Я также пользуюсь решением RegEx. Код будет намного чище. Я бы не стал использовать toLowerCase() в ситуациях, когда я знал, что строки будут большими, поскольку строки являются неизменными и должны быть скопированы. Кроме того, решение matches() может сбивать с толку, потому что оно принимает регулярное выражение в качестве аргумента (поиск "Need $le" холод будет проблематичным).

Основываясь на некоторых из приведенных выше примеров:

public boolean containsIgnoreCase( String haystack, String needle ) {
  if(needle.equals(""))
    return true;
  if(haystack == null || needle == null || haystack .equals(""))
    return false; 

  Pattern p = Pattern.compile(needle,Pattern.CASE_INSENSITIVE+Pattern.LITERAL);
  Matcher m = p.matcher(haystack);
  return m.find();
}

example call: 

String needle = "Need$le";
String haystack = "This is a haystack that might have a need$le in it.";
if( containsIgnoreCase( haystack, needle) ) {
  System.out.println( "Found " + needle + " within " + haystack + "." );
}

(Примечание: вам может понадобиться обрабатывать NULL и пустые строки по-разному в зависимости от ваших потребностей. Я думаю, что они, как я есть, ближе к спецификации Java для строк.)

Критические решения скорости могут включать итерацию через символ стога сена, характерный для первого символа иглы. Когда первый символ сопоставляется (случай insenstively), начинайте итерирование по символу иглы по символу, ища соответствующий символ в стоге сена и возвращающий "истину", если все символы совпадают. Если встречается несогласованный символ, возобновите итерацию через стог сена у следующего символа, возвращая "false", если достигнута позиция > haystack.length() - needle.length().

Ответ 6

Я бы использовал комбинацию метода contains и метода toUpper, которые являются частью класса String. Ниже приведен пример:

String string1 = "AAABBBCCC"; 
String string2 = "DDDEEEFFF";
String searchForThis = "AABB";

System.out.println("Search1="+string1.toUpperCase().contains(searchForThis.toUpperCase()));

System.out.println("Search2="+string2.toUpperCase().contains(searchForThis.toUpperCase()));

Это вернет:

Search1 = истина
    Search2 = ложь