Angenommen, ich habe zwei Saiten,
String s1 = "AbBaCca";
String s2 = "bac";
Ich möchte eine Überprüfung durchführen, die die s2
darin enthaltene Rückgabe zurückgibt s1
. Ich kann das machen mit:
return s1.contains(s2);
Ich bin mir ziemlich sicher, dass zwischen contains()
Groß- und Kleinschreibung unterschieden wird, aber ich kann dies nicht sicher anhand der Dokumentation feststellen. Wenn ja, dann wäre meine beste Methode wahrscheinlich so etwas wie:
return s1.toLowerCase().contains(s2.toLowerCase());
Abgesehen davon gibt es einen anderen (möglicherweise besseren) Weg, dies zu erreichen, ohne sich um die Groß- und Kleinschreibung zu kümmern?
Antworten:
Ja, enthält Groß- und Kleinschreibung. Sie können java.util.regex.Pattern mit dem Flag CASE_INSENSITIVE verwenden, um die Groß- und Kleinschreibung nicht zu berücksichtigen:
BEARBEITEN: Wenn s2 Regex-Sonderzeichen enthält (von denen es viele gibt), ist es wichtig, diese zuerst zu zitieren. Ich habe meine Antwort korrigiert, da es die erste ist, die die Leute sehen werden, aber stimmen Sie die von Matt Quail ab, seit er darauf hingewiesen hat.
quelle
Pattern.CASE_INSENSITIVE
, funktioniert dies nur für ASCII-Zeichen (dh "Ä" stimmt nicht mit "ä" überein). Man muss zusätzlich dasUNICODE_CASE
Flag angeben, um dies zu erreichen.Pattern
leistungsfähiger alss1.toLowerCase().contains(s2.toLowerCase())
?Pattern.compile(Pattern.quote(needle), Pattern.CASE_INSENSITIVE).matcher(haystack).find()
Ein Problem mit der Antwort von Dave L. ist, wenn s2 Regex-Markups wie
\d
usw. enthält.Sie möchten Pattern.quote () auf s2 aufrufen:
quelle
toLowerCase().contains()
ist schneller. Ich habe eine Geschwindigkeitsanalyse durchgeführt, siehe meine Antwort für Ergebnisse: stackoverflow.com/a/25379180/1705598Pattern.UNICODE_CASE
Flagge hinzufügen . Könnten Sie dies bitte bestätigen?Sie können verwenden
Die Apache Commons- Bibliothek ist für solche Dinge sehr nützlich. Und dieser spezielle Ausdruck ist möglicherweise besser als reguläre Ausdrücke, da Regex in Bezug auf die Leistung immer teuer ist.
quelle
String.regionMatches
, das zeichenweise Konvertierungen verwendet, also nein. Außerdem wirdcontainsIgnoreCase("ß", "ss")
-1 zurückgegeben, was in jedem Gebietsschema falsch ist (das deutsche "scharfe s" kapitalisiert zu "ss".Eine schnellere Implementierung: Nutzen
String.regionMatches()
Die Verwendung von Regexp kann relativ langsam sein. Es ist (langsam) egal, ob Sie nur in einem Fall überprüfen möchten. Aber wenn Sie ein Array oder eine Sammlung von Tausenden oder Hunderttausenden von Zeichenfolgen haben, kann es ziemlich langsam werden.
Die unten dargestellte Lösung verwendet weder reguläre Ausdrücke noch
toLowerCase()
(was auch langsam ist, weil es andere Zeichenfolgen erstellt und diese nach der Prüfung einfach wegwirft).Die Lösung baut auf der String.regionMatches () -Methode auf, die unbekannt zu sein scheint. Es wird geprüft, ob zwei
String
Regionen übereinstimmen. Wichtig ist jedoch, dass es auch eine Überlastung mit einem praktischenignoreCase
Parameter gibt.Geschwindigkeitsanalyse
Diese Geschwindigkeitsanalyse bedeutet nicht, Raketenwissenschaft zu sein, sondern nur ein grobes Bild davon, wie schnell die verschiedenen Methoden sind.
Ich vergleiche 5 Methoden.
String.contains()
.String.contains()
mit der vorab zwischengespeicherten Teilzeichenfolge in Kleinbuchstaben. Diese Lösung ist bereits nicht so flexibel, da sie einen vordefinierten Teilstring testet.Pattern.compile().matcher().find()
...)Pattern
. Diese Lösung ist bereits nicht so flexibel, da sie einen vordefinierten Teilstring testet.Ergebnisse (durch 10 Millionen Aufruf der Methode):
Pattern
: 1845 msErgebnisse in einer Tabelle:
Unsere Methode ist 4x schneller als die Verwendung von Kleinbuchstaben und die Verwendung
contains()
, 10x schneller als die Verwendung regulärer Ausdrücke und 3x schneller, selbst wenn diePattern
vorab zwischengespeichert ist (und die Flexibilität bei der Suche nach einem beliebigen Teilstring verliert).Analyse-Testcode
Wenn Sie interessiert sind, wie die Analyse durchgeführt wurde, finden Sie hier die vollständige ausführbare Anwendung:
quelle
ß
(deutsches scharfes S; groß geschriebenSS
) und auch für einige andere Zeichen fehlschlägt (siehe die Quelle vonString.regionMatches
, die beide Konvertierungen versucht).StringUtils.containsIgnoreCase()
ist, dass sowohl meine Lösung als auch die Apache-regionMatches()
Methode eine Methode (in einem Zyklus) verwenden, aber selbst das ist nicht dasselbe, wie ichString.regionMatches()
und Apache-AufrufeCharSequenceUtils.regionMatches()
.CharSequenceUtils.regionMatches
ruftString.regionMatches
eigentlich nur an. Wie auch immer, mein Punkt war es, die Information zu geben, dass jemand, der bereits StringUtils lib verwendet, es einfach aufrufen kann, weil es ein effizienter Weg zu sein scheint, wie Sie es mit Ihrem Benchmark beweisen. Wenn ich Apache lib nicht verwenden würde, würde ich definitiv Ihre Methode verwenden;)Eine einfachere Möglichkeit, dies zu tun (ohne sich um den Mustervergleich zu kümmern), besteht darin, beide
String
s in Kleinbuchstaben umzuwandeln :quelle
Ja, das ist erreichbar:
Dieser Code gibt den String "TRUE!" Zurück. als sich herausstellte, dass Ihre Charaktere enthalten waren.
quelle
s2
. Wenn Sie nicht über solche Details sprechen, wird diese nicht kompiliert, und wenn dies der Fall ist, wird eine Zeichenfolge zurückgegeben.Sie können reguläre Ausdrücke verwenden und es funktioniert:
quelle
Hier sind einige Unicode-freundliche, die Sie erstellen können, wenn Sie ICU4j verwenden. Ich denke, "Groß- / Kleinschreibung ignorieren" ist für die Methodennamen fraglich, da Primärstärkevergleiche Groß- und Kleinschreibung zwar ignorieren, sie jedoch als länderabhängig beschrieben werden. Aber es ist hoffentlich in einer Weise vom Gebietsschema abhängig, die der Benutzer erwarten würde.
quelle
Ich habe einen Test durchgeführt, bei dem eine Übereinstimmung einer Zeichenfolge ohne Berücksichtigung der Groß- und Kleinschreibung festgestellt wurde. Ich habe einen Vektor von 150.000 Objekten, alle mit einer Zeichenfolge als einem Feld, und wollte die Teilmenge finden, die einer Zeichenfolge entspricht. Ich habe drei Methoden ausprobiert:
Konvertieren Sie alles in Kleinbuchstaben
Verwenden Sie die Methode String match ()
Verwenden Sie reguläre Ausdrücke
Timing-Ergebnisse sind:
Keine versuchte Übereinstimmung: 20 ms
Zum Verringern der Übereinstimmung: 182 ms
String-Übereinstimmungen: 278 ms
Regulärer Ausdruck: 65 ms
Der reguläre Ausdruck scheint für diesen Anwendungsfall der schnellste zu sein.
quelle
Es gibt eine einfache, übersichtliche Möglichkeit, das Regex-Flag zu verwenden (Groß- und Kleinschreibung wird nicht berücksichtigt {i}):
quelle
Ich bin nicht sicher, was Ihre Hauptfrage hier ist, aber ja, .contains unterscheidet zwischen Groß- und Kleinschreibung.
quelle
Grundsätzlich ist es eine Methode, die zwei Zeichenfolgen benötigt. Es soll sich um eine Version handeln, bei der die Groß- und Kleinschreibung nicht berücksichtigt wird. Wenn Sie die Methode includes verwenden, möchten Sie sehen, ob eine Zeichenfolge in der anderen enthalten ist.
Diese Methode verwendet die Zeichenfolge "sub" und prüft, ob sie den Teilzeichenfolgen der Containerzeichenfolge entspricht, deren Länge der von "sub" entspricht. Wenn Sie sich die
for
Schleife ansehen, werden Sie feststellen, dass sie in Teilzeichenfolgen (dh der Länge des "Sub") über die Containerzeichenfolge iteriert.Bei jeder Iteration wird überprüft, ob sich die Teilzeichenfolge der Containerzeichenfolge
equalsIgnoreCase
im Sub befindet.quelle
Wenn Sie eine ASCII-Zeichenfolge in einer anderen ASCII-Zeichenfolge wie einer URL suchen müssen, ist meine Lösung besser. Ich habe die Methode von icza und meine auf Geschwindigkeit getestet und hier sind die Ergebnisse:
Der Code:
quelle
quelle
quelle
Wir können Stream mit anyMatch verwenden und enthält Java 8
quelle
Oder Sie können einen einfachen Ansatz verwenden und einfach die Groß- / Kleinschreibung der Zeichenfolge in die Groß- / Kleinschreibung der Teilzeichenfolge konvertieren und dann die Methode includes verwenden.
quelle
quelle
Sie könnten einfach so etwas tun:
quelle