Hoe controleer ik in Java of een tekenreeks een subtekenreeks bevat (hoofdletters negeren)?

Ik heb twee Stringen, str1en str2. Hoe controleer ik of str2is opgenomen in str1, hoofdletters negerend?


Antwoord 1, autoriteit 100%

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

Antwoord 2, autoriteit 13%

Hoe zit het met 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.*");

Antwoord 3, autoriteit 3%

Als u org.apache.commons.lang.StringUtilskunt gebruiken, raad ik u aan het volgende te gebruiken:

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

Antwoord 4, autoriteit 2%

U kunt de methode toLowerCase()gebruiken:

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() )
}

Noem het dan met:

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

Merk op dat u deze opnieuw kunt gebruiken door uw eigen methode te maken. Als iemand u erop wijst dat u containsmoet gebruiken in plaats van indexOf, hoeft u slechts één regel code te wijzigen.


Antwoord 5

Ik ben ook voorstander van de RegEx-oplossing. De code zal veel schoner zijn. Ik zou aarzelen om toLowerCase() te gebruiken in situaties waarin ik wist dat de strings groot zouden worden, aangezien strings onveranderlijk zijn en gekopieerd zouden moeten worden. Ook kan de match()-oplossing verwarrend zijn omdat er een reguliere expressie als argument voor nodig is (zoeken naar “Need$le” zou problematisch zijn).

Voortbouwend op enkele van de bovenstaande voorbeelden:

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 + "." );
}

(Opmerking: u wilt mogelijk anders omgaan met NULL en lege tekenreeksen, afhankelijk van uw behoeften. Ik denk dat de manier waarop ik het heb dichter bij de Java-specificatie voor tekenreeksen ligt.)

Snelheidskritieke oplossingen kunnen bestaan uit het karakter voor karakter doorlopen van de hooiberg op zoek naar het eerste karakter van de naald. Wanneer het eerste teken overeenkomt (hoofdlettergevoelig), begin dan teken voor teken door de naald te bladeren, zoek het overeenkomstige teken in de hooiberg en geef “waar” terug als alle tekens overeenkomen. Als een niet-overeenkomend teken wordt aangetroffen, hervat dan de iteratie door de hooiberg bij het volgende teken, waarbij “false” wordt geretourneerd als een positie > haystack.length() – needle.length() is bereikt.


Antwoord 6

Ik zou een combinatie gebruiken van de methode bevat en de methode toUpperdie deel uitmaken van de klasse String. Een voorbeeld staat hieronder:

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()));

Dit keert terug:

Zoeken1=waar
Zoeken2=false

Other episodes