Dis que j'ai deux cordes,
String s1 = "AbBaCca";
String s2 = "bac";
Je veux effectuer un retour de vérification qui s2
est contenu dans s1
. Je peux le faire avec:
return s1.contains(s2);
Je suis à peu près sûr que cela contains()
respecte la casse, mais je ne peux pas le déterminer avec certitude en lisant la documentation. Si c'est le cas, je suppose que ma meilleure méthode serait quelque chose comme:
return s1.toLowerCase().contains(s2.toLowerCase());
Tout cela mis à part, existe-t-il une autre façon (peut-être meilleure) d'accomplir cela sans se soucier de la sensibilité à la casse?
Réponses:
Oui, contient est sensible à la casse. Vous pouvez utiliser java.util.regex.Pattern avec l'indicateur CASE_INSENSITIVE pour la correspondance insensible à la casse:
EDIT: Si s2 contient des caractères spéciaux regex (dont il y en a beaucoup), il est important de le citer d'abord. J'ai corrigé ma réponse car c'est la première que les gens verront, mais votez pour Matt Quail depuis qu'il l'a souligné.
la source
Pattern.CASE_INSENSITIVE
, cela ne fonctionne que pour les caractères ASCII (c'est-à-dire que "Ä" ne correspondra pas à "ä"). Il faut également spécifier leUNICODE_CASE
drapeau pour y parvenir.Pattern
plus performante ques1.toLowerCase().contains(s2.toLowerCase())
?Pattern.compile(Pattern.quote(needle), Pattern.CASE_INSENSITIVE).matcher(haystack).find()
Un problème avec la réponse de Dave L. est lorsque s2 contient un balisage d'expression régulière tel que
\d
, etc.Vous voulez appeler Pattern.quote () sur s2:
la source
toLowerCase().contains()
c'est plus rapide. J'ai effectué une analyse de vitesse, voir ma réponse pour les résultats: stackoverflow.com/a/25379180/1705598Pattern.UNICODE_CASE
drapeau. Pourriez-vous s'il vous plaît confirmer cela?Vous pouvez utiliser
La bibliothèque Apache Commons est très utile pour ce genre de chose. Et celle-ci peut être meilleure que les expressions régulières car l'expression régulière est toujours coûteuse en termes de performances.
la source
String.regionMatches
, qui utilise des conversions par caractère, donc non. De plus,containsIgnoreCase("ß", "ss")
retourne -1, ce qui est faux dans tous les paramètres régionaux (le "sharp s" allemand capitalise en "ss".Une mise en œuvre plus rapide: utilisation
String.regionMatches()
L'utilisation d'expressions régulières peut être relativement lente. Cela (être lent) n'a pas d'importance si vous voulez simplement vérifier dans un cas. Mais si vous avez un tableau ou une collection de milliers ou de centaines de milliers de chaînes, les choses peuvent devenir assez lentes.
La solution présentée ci-dessous n'utilise pas d'expressions régulières ni
toLowerCase()
(ce qui est également lent car il crée une autre chaîne et la jette juste après la vérification).La solution s'appuie sur la méthode String.regionMatches () qui semble inconnue. Il vérifie si 2
String
régions correspondent, mais ce qui est important, c'est qu'il a également une surcharge avec unignoreCase
paramètre pratique .Analyse de vitesse
Cette analyse de la vitesse ne signifie pas être une science de fusée, juste une image approximative de la rapidité des différentes méthodes.
Je compare 5 méthodes.
String.contains()
.String.contains()
avec la sous-chaîne pré-mise en cache et en minuscules. Cette solution n'est déjà pas aussi flexible car elle teste une sous-chaîne prédéfinie.Pattern.compile().matcher().find()
...)Pattern
. Cette solution n'est déjà pas aussi flexible car elle teste une sous-chaîne prédéfinie.Résultats (en appelant la méthode 10 millions de fois):
Pattern
: 1845 msRésultats dans un tableau:
Notre méthode est 4 fois plus rapide par rapport à l'utilisation de minuscules et à l'utilisation
contains()
, 10 fois plus rapide que l' utilisation d'expressions régulières et également 3 fois plus rapide même si lePattern
est pré-mis en cache (et perd la flexibilité de vérifier une sous-chaîne arbitraire).Code de test d'analyse
Si vous êtes intéressé par la façon dont l'analyse a été effectuée, voici l'application exécutable complète:
la source
ß
(S allemand pointu; en majuscule pourSS
) et aussi pour certains autres personnages (voir la source deString.regionMatches
, qui essaie les deux conversions).StringUtils.containsIgnoreCase()
est que ma solution et celle d'Apache utilisent uneregionMatches()
méthode (dans un cycle), mais même ce n'est pas la même chose que j'appelleString.regionMatches()
et les appels ApacheCharSequenceUtils.regionMatches()
.CharSequenceUtils.regionMatches
appelle juste enString.regionMatches
fait. Quoi qu'il en soit, mon point était de donner l'info, que si quelqu'un utilise déjà la bibliothèque StringUtils, il peut simplement l'appeler parce que cela semble être un moyen efficace comme vous le prouvez avec votre référence. Si je n'utilisais pas Apache lib, j'utiliserais définitivement votre méthode;)Une façon plus simple de le faire (sans se soucier de la correspondance des modèles) serait de convertir les deux
String
s en minuscules:la source
Oui, c'est réalisable:
Ce code renverra la chaîne "TRUE!" car il a constaté que vos personnages étaient contenus.
la source
s2
. Ne pas parler de tels détails comme celui-ci ne se compile pas et s'il le faisait, il retournerait une chaîne.Vous pouvez utiliser des expressions régulières , et cela fonctionne:
la source
Voici quelques-uns compatibles avec Unicode que vous pouvez créer si vous utilisez ICU4j. Je suppose que "ignorer la casse" est discutable pour les noms de méthode, car bien que les comparaisons de force principales ignorent la casse, elles sont décrites comme étant spécifiques aux paramètres régionaux. Mais il est à espérer que cela dépend des paramètres régionaux d'une manière attendue par l'utilisateur.
la source
J'ai fait un test pour trouver une correspondance insensible à la casse d'une chaîne. J'ai un vecteur de 150 000 objets tous avec une chaîne comme un champ et je voulais trouver le sous-ensemble qui correspondait à une chaîne. J'ai essayé trois méthodes:
Convertir tout en minuscules
Utilisez la méthode String matches ()
Utilisez des expressions régulières
Les résultats de chronométrage sont:
Aucune tentative de correspondance: 20 ms
Pour réduire la correspondance: 182 ms
Correspondances de chaînes: 278 ms
Expression régulière: 65 ms
L'expression régulière semble être la plus rapide pour ce cas d'utilisation.
la source
Il existe un moyen simple et concis, en utilisant le drapeau regex (insensible à la casse {i}):
la source
Je ne sais pas quelle est votre question principale ici, mais oui, .contains est sensible à la casse.
la source
Fondamentalement, c'est une méthode qui prend deux chaînes. Il est censé être une version non sensible à la casse de contains (). Lorsque vous utilisez la méthode contains, vous voulez voir si une chaîne est contenue dans l'autre.
Cette méthode prend la chaîne qui est «sous» et vérifie si elle est égale aux sous-chaînes de la chaîne de conteneur qui sont égales en longueur au «sous». Si vous regardez la
for
boucle, vous verrez qu'elle itère dans des sous-chaînes (qui sont la longueur du "sous") sur la chaîne de conteneur.Chaque itération vérifie si la sous-chaîne de la chaîne de conteneur correspond
equalsIgnoreCase
au sous.la source
Si vous devez rechercher une chaîne ASCII dans une autre chaîne ASCII, telle qu'une URL , vous trouverez ma solution meilleure. J'ai testé la méthode et la mienne d'icza pour la vitesse et voici les résultats:
Le code:
la source
la source
la source
Nous pouvons utiliser stream avec anyMatch et contient de Java 8
la source
ou vous pouvez utiliser une approche simple et convertir simplement le cas de la chaîne en cas de sous-chaîne, puis utiliser la méthode contient.
la source
la source
Vous pouvez simplement faire quelque chose comme ceci:
la source