3450 votes

Insensible à la casse "Contient(string)".

Existe-t-il un moyen de faire en sorte que l'élément suivant renvoie vrai ?

string title = "ASTRINGTOTEST";
title.Contains("string");

Il ne semble pas y avoir de surcharge qui me permette de régler la sensibilité à la casse Actuellement, je les mets en majuscules toutes les deux, mais c'est tout simplement idiot (je fais référence à la fonction i18n les problèmes que posent les boyaux ascendants et descendants).

UPDATE
Cette question est ancienne et depuis, je me suis rendu compte que j'ai demandé une réponse simple pour un sujet vraiment vaste et difficile si l'on veut l'étudier à fond.
Dans la plupart des cas, dans les bases de données monolingues et anglaises. ce La réponse suffira. Je pense que, comme la plupart des personnes qui viennent ici appartiennent à cette catégorie, c'est la réponse la plus populaire.
Ce site Cette réponse soulève toutefois le problème inhérent au fait que nous ne pouvons pas comparer des textes sans tenir compte de la casse tant que nous ne savons pas que les deux textes appartiennent à la même culture et que nous ne savons pas quelle est cette culture. C'est peut-être une réponse moins populaire, mais je pense qu'elle est plus correcte et c'est pourquoi je l'ai marquée comme telle.

0 votes

Essayez celui-ci : Yourculture.CompareInfo.IndexOf(paragraphe, mot, CompareOptions.IgnoreCase) >= 0

3144voto

JaredPar Points 333733

Vous pourriez utiliser le String.IndexOf Méthode et passer StringComparison.OrdinalIgnoreCase comme type de recherche à utiliser :

string title = "STRING";
bool contains = title.IndexOf("string", StringComparison.OrdinalIgnoreCase) >= 0;

Il est encore mieux de définir une nouvelle méthode d'extension pour les chaînes de caractères :

public static class StringExtensions
{
    public static bool Contains(this string source, string toCheck, StringComparison comp)
    {
        return source?.IndexOf(toCheck, comp) >= 0;
    }
}

Notez, que propagation de la nullité ?. est disponible depuis C# 6.0 (VS 2015), pour les versions plus anciennes utiliser

if (source == null) return false;
return source.IndexOf(toCheck, comp) >= 0;

UTILISATION :

string title = "STRING";
bool contains = title.Contains("string", StringComparison.OrdinalIgnoreCase);

1 votes

Quel serait le meilleur endroit pour placer quelque chose comme ça dans la structure d'une application ?

1 votes

@Andi, j'ai généralement un couple de fichiers de code avec des méthodes d'extension d'usage général où cela pourrait aller.

0 votes

@JaredPar : Je suis curieux de savoir si .Net 4 ou .Net 4.5 a cette fonction intégrée, le sauriez-vous ?

1581voto

Colonel Panic Points 18390

Pour tester si la chaîne paragraph contient la chaîne de caractères word (merci @QuarterMeister)

culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0

culture est l'instance de CultureInfo décrivant la langue dans laquelle le texte est écrit.

Cette solution est transparente sur la définition de l'insensibilité à la casse, qui dépend de la langue. . Par exemple, la langue anglaise utilise les caractères I et i pour les versions majuscule et minuscule de la neuvième lettre, alors que la langue turque utilise ces caractères pour la version onzième et douzième lettres de son alphabet de 29 lettres. La version turque en majuscules du "i" est le caractère inconnu "I".

Ainsi, les cordes tin et TIN sont le même mot en anglais mais des mots différents en turc . Si je comprends bien, l'un signifie "esprit" et l'autre est un mot onomatopée. (Turcs, corrigez-moi si je me trompe, ou proposez un meilleur exemple)

Pour résumer, vous ne pouvez répondre qu'à la question "ces deux chaînes sont-elles identiques mais dans des cas différents". si vous savez dans quelle langue est le texte . Si vous ne le savez pas, il vous faudra tenter votre chance. Étant donné l'hégémonie de l'anglais dans les logiciels, vous devriez probablement recourir à CultureInfo.InvariantCulture parce qu'il sera faux de manière familière.

0 votes

Je comprends votre point de vue et vous avez probablement raison. Cette question est ancienne et je dois la relire, mais je pense que je vais changer la réponse acceptée.

79 votes

Pourquoi pas ? culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0 ? Cela utilise la bonne culture et est insensible à la casse, cela n'alloue pas de chaînes temporaires en minuscules, et cela évite la question de savoir si la conversion en minuscules et la comparaison est toujours la même qu'une comparaison insensible à la casse.

0 votes

@Quartermeister ça va marcher. J'ai essayé de trouver comment CompareInfo.IndexOf définit une comparaison insensible à la casse, mais la méthode se contente d'envelopper l'option InternalFindNLSStringEx qui n'est pas documenté.

279voto

mkchandler Points 2389

Vous pouvez utiliser IndexOf() comme ça :

string title = "STRING";

if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
{
    // The string exists in the original
}

Puisque 0 (zéro) peut être un indice, vous vérifiez par rapport à -1.

MSDN

La position de l'index basé sur zéro de la valeur si cette chaîne est trouvée, ou -1 si elle n'est pas trouvée. Si la valeur est String.Empty, la valeur de retour est 0.

161voto

Jed Points 3592

Solution alternative utilisant Regex :

bool contains = Regex.IsMatch("StRiNG to search", Regex.Escape("string"), RegexOptions.IgnoreCase);

7 votes

Bonne idée, nous avons également beaucoup de combinaisons de bits dans RegexOptions, par exemple RegexOptions.IgnoreCase & RegexOptions.IgnorePatternWhitespace & RegexOptions.CultureInvariant; pour tout le monde si ça peut aider.

8 votes

Je dois dire que je préfère cette méthode, même si j'utilise IsMatch par souci de propreté.

38 votes

Pire encore, comme la chaîne de recherche est interprétée comme une expression rationnelle, un certain nombre de caractères de ponctuation entraîneront des résultats incorrects (ou déclencheront une exception due à une expression non valide). Essayez de rechercher "." sur "This is a sample string that doesn't contain the search string" . Ou essayez de chercher "(invalid" d'ailleurs.

56voto

FeiBao 飞豹 Points 279

Un problème avec la réponse est qu'elle lève une exception si une chaîne est nulle. Vous pouvez l'ajouter en tant que vérification pour qu'elle ne le fasse pas :

public static bool Contains(this string source, string toCheck, StringComparison comp)
{
    if (string.IsNullOrEmpty(toCheck) || string.IsNullOrEmpty(source))
        return true;

    return source.IndexOf(toCheck, comp) >= 0;
}

9 votes

Si toCheck est une chaîne vide, il doit renvoyer true selon la documentation sur les conteneurs : "vrai si le paramètre value se trouve dans cette chaîne, ou si value est la chaîne vide ("") ; sinon, false".

4 votes

D'après le commentaire d'amurra ci-dessus, le code suggéré ne doit-il pas être corrigé ? Et cela ne devrait-il pas être ajouté à la réponse acceptée, de sorte que la meilleure réponse soit la première ?

16 votes

Maintenant, cela retournera vrai si la source est une chaîne vide ou nulle, peu importe ce que toCheck est. Cela ne peut pas être correct. De plus, IndexOf renvoie déjà la réponse vraie si toCheck est une chaîne vide et si la source n'est pas nulle. Ce dont nous avons besoin ici, c'est d'une vérification de null. Je suggère que si (source == null || valeur == null) retourne false ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X