465 Stimmen

Wie kann man in Java prüfen, ob eine Zeichenkette eine andere Zeichenkette enthält, ohne die Groß- und Kleinschreibung zu berücksichtigen?

Angenommen, ich habe zwei Strings,

String s1 = "AbBaCca";
String s2 = "bac";

Ich möchte eine Prüfung durchführen, die Folgendes zurückgibt s2 ist enthalten in s1 . Ich kann dies mit tun:

return s1.contains(s2);

Ich bin mir ziemlich sicher, dass contains() zwischen Groß- und Kleinschreibung unterscheidet, aber ich kann das aus der Dokumentation nicht mit Sicherheit herauslesen. Wenn es ist, dann nehme ich an, meine beste Methode wäre etwas wie:

return s1.toLowerCase().contains(s2.toLowerCase());

Abgesehen davon, gibt es eine andere (möglicherweise bessere) Möglichkeit, dies zu erreichen, ohne sich um die Groß- und Kleinschreibung zu kümmern?

20voto

Bilbo Baggins Punkte 247

Ja, das ist machbar:

String s1 = "abBaCca";
String s2 = "bac";

String s1Lower = s1;

//s1Lower is exact same string, now convert it to lowercase, I left the s1 intact for print purposes if needed

s1Lower = s1Lower.toLowerCase();

String trueStatement = "FALSE!";
if (s1Lower.contains(s2)) {

    //THIS statement will be TRUE
    trueStatement = "TRUE!"
}

return trueStatement;

Dieser Code gibt die Zeichenkette "TRUE!" zurück, da er festgestellt hat, dass Ihre Zeichen enthalten waren.

8voto

Shiv Punkte 1249

Sie können verwenden reguläre Ausdrücke und es funktioniert:

boolean found = s1.matches("(?i).*" + s2+ ".*");

4voto

Hakanai Punkte 10729

Hier sind einige Unicode-freundliche, die man mit ICU4j erstellen kann. Ich schätze, dass "Groß-/Kleinschreibung ignorieren" für die Methodennamen fragwürdig ist, denn obwohl primäre Stärkevergleiche die Groß-/Kleinschreibung ignorieren, wird es so beschrieben, als seien die Besonderheiten lokalabhängig. Aber es ist hoffentlich lokalabhängig in einer Weise, die der Benutzer erwarten würde.

public static boolean containsIgnoreCase(String haystack, String needle) {
    return indexOfIgnoreCase(haystack, needle) >= 0;
}

public static int indexOfIgnoreCase(String haystack, String needle) {
    StringSearch stringSearch = new StringSearch(needle, haystack);
    stringSearch.getCollator().setStrength(Collator.PRIMARY);
    return stringSearch.first();
}

3voto

Jan Newmarch Punkte 341

Ich habe einen Test durchgeführt, bei dem die Groß- und Kleinschreibung einer Zeichenkette nicht berücksichtigt wurde. Ich habe einen Vektor mit 150.000 Objekten, die alle eine Zeichenfolge als ein Feld haben, und wollte die Teilmenge finden, die mit einer Zeichenfolge übereinstimmt. Ich habe drei Methoden ausprobiert:

  1. Alles in Kleinbuchstaben umwandeln

    for (SongInformation song: songs) {
        if (song.artist.toLowerCase().indexOf(pattern.toLowercase() > -1) {
                ...
        }
    }
  2. Verwenden Sie die Methode String matches()

    for (SongInformation song: songs) {
        if (song.artist.matches("(?i).*" + pattern + ".*")) {
        ...
        }
    }
  3. Reguläre Ausdrücke verwenden

    Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
    Matcher m = p.matcher("");
    for (SongInformation song: songs) {
        m.reset(song.artist);
        if (m.find()) {
        ...
        }
    }

Die Ergebnisse der Zeitmessung sind:

  • Kein Trefferversuch: 20 msek

  • Um die Übereinstimmung zu verringern: 182 msek

  • String passt: 278 msek

  • Regulärer Ausdruck: 65 msek

Der reguläre Ausdruck scheint für diesen Anwendungsfall am schnellsten zu sein.

3voto

Mr.Q Punkte 3879

Es gibt einen einfachen, prägnanten Weg, der das Regex-Flag verwendet (Groß- und Kleinschreibung wird nicht berücksichtigt {i}):

 String s1 = "hello abc efg";
 String s2 = "ABC";
 s1.matches(".*(?i)"+s2+".*");

/*
 * .*  denotes every character except line break
 * (?i) denotes case insensitivity flag enabled for s2 (String)
 * */

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X