web-dev-qa-db-fra.com

Insensible à la casse 'Contient (chaîne)'

Existe-t-il un moyen de rendre vrai le retour suivant?

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

Il ne semble pas exister de surcharge qui me permette de définir la sensibilité à la casse. Pour le moment, je suis en majuscule, mais c’est idiot (je parle ici de la question { i18n } et vers le bas du boîtier).

METTRE À JOUR
Cette question est ancienne et depuis lors, je me rends compte que j’ai demandé une réponse simple à un sujet très vaste et difficile, si vous tenez à bien l’étudier.
Dans la plupart des cas, en langage monolingue, les bases de code anglais this réponse suffiront. Je pense que parce que la plupart des gens qui viennent ici tombent dans cette catégorie, c'est la réponse la plus populaire.
This answer soulève toutefois le problème inhérent que nous ne pouvons pas comparer un texte insensible à la casse avant que nous sachions que les deux textes sont la même culture et que nous savons quelle est cette culture. C'est peut-être une réponse moins populaire, mais je pense que c'est plus correct et c'est pourquoi je l'ai marquée comme telle.

2579
Boris Callens

Pour tester si la chaîne paragraph contient la chaîne 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 majuscules et minuscules de la neuvième lettre, tandis que la langue turque utilise ces caractères pour les onzième et douzième lettres de son alphabet long de 29 lettres. La version turque en majuscule de «i» est le caractère inconnu «İ».

Ainsi, les chaînes 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 suggérez un meilleur exemple)

Pour résumer, vous pouvez uniquement répondre à la question "ces deux chaînes sont-elles identiques, mais dans des cas différents" si vous connaissez la langue dans laquelle le texte est écrit. Si vous ne savez pas, vous devrez prendre une punt. Compte tenu de l'hégémonie de l'anglais dans les logiciels, vous devriez probablement recourir à CultureInfo.InvariantCulture , parce que ce sera faux de manière familière.

1202
Colonel Panic

Vous pouvez utiliser la méthode String.IndexOf et transmettre StringComparison.OrdinalIgnoreCase comme type de recherche à utiliser:

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

Encore mieux est de définir une nouvelle méthode d’extension pour string:

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

Notez que la propagation null?. est disponible depuis C # 6.0 (VS 2015), pour les versions plus anciennes, utilisez

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

USAGE: 

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

Vous pouvez utiliser IndexOf() comme ceci:

string title = "STRING";

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

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

MSDN

La position d'index de base zéro de value si cette chaîne est trouvée, ou -1 si ce n'est pas le cas. Si value est String.Empty, la valeur de retour est 0.

212
mkchandler

Solution alternative utilisant Regex:

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

Vous pouvez toujours juste commencer par monter ou descendre les cordes. 

string title = "string":
title.ToUpper().Contains("STRING")  // returns true

Oups, je viens de voir ce dernier morceau. Une comparaison insensible à la casse permettrait *probably* de faire de même, et si les performances ne sont pas un problème, je ne vois pas de problème pour créer des copies majuscules et les comparer. J'aurais juré avoir déjà vu une comparaison insensible à la casse ...

70
Ed S.

Un problème avec la réponse est qu'il lève une exception si une chaîne est nulle. Vous pouvez ajouter cela comme un chèque pour ne 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;
} 
48
FeiBao 飞豹

La classe StringExtension est la voie à suivre. J'ai combiné quelques-uns des articles ci-dessus pour donner un exemple de code complet:

public static class StringExtensions
{
    /// <summary>
    /// Allows case insensitive checks
    /// </summary>
    public static bool Contains(this string source, string toCheck, StringComparison comp)
    {
        return source.IndexOf(toCheck, comp) >= 0;
    }
}
34
Andrew

C'est propre et simple.

Regex.IsMatch(file, fileNamestr, RegexOptions.IgnoreCase)
34
takirala

OrdinalIgnoreCase, CurrentCultureIgnoreCase ou InvariantCultureIgnoreCase?

Comme cela manque, voici quelques recommandations sur le moment d'utiliser lequel:

Dos

  • Utilisez StringComparison.OrdinalIgnoreCase pour les comparaisons en tant que valeur par défaut sûre pour la correspondance de chaînes dépendant de la culture.
  • Utilisez les comparaisons StringComparison.OrdinalIgnoreCase Pour augmenter la vitesse.
  • Utilisez les opérations de chaîne StringComparison.CurrentCulture-based Lorsque vous affichez la sortie à l'utilisateur.
  • Basculez l'utilisation actuelle des opérations de chaîne basées sur l'invariant Culture pour utiliser le StringComparison.Ordinal ou StringComparison.OrdinalIgnoreCase non linguistique lorsque la comparaison est
    linguistiquement non pertinent (symbolique, par exemple). 
  • Utilisez ToUpperInvariant plutôt que ToLowerInvariant lorsque Normalisant les chaînes à des fins de comparaison.

À ne pas faire

  • Utilisez des surcharges pour les opérations sur chaînes qui ne spécifient pas explicitement .__ ou implicitement le mécanisme de comparaison des chaînes.
  • Utiliser une chaîne basée sur StringComparison.InvariantCulture
    opérations dans la plupart des cas; une des rares exceptions serait
    données persistantes linguistiquement significatives mais culturellement agnostiques.

Sur la base de ces règles, vous devriez utiliser:

string title = "STRING";
if (title.IndexOf("string", 0, StringComparison.[YourDecision]) != -1)
{
    // The string exists in the original
}

alors que [YourDecision] dépend des recommandations ci-dessus.

lien de source: http://msdn.Microsoft.com/en-us/library/ms973919.aspx

24
Fabian Bigler

.NET Core 2.0+ uniquement (à partir de maintenant)

.NET Core a eu une paire de méthodes pour résoudre ce problème depuis la version 2.0:

  • String.Contains (Char, StringComparison )
  • String.Contains (String, StringComparison )

Exemple:

"Test".Contains("test", System.StringComparison.CurrentCultureIgnoreCase);

Avec le temps, ils se retrouveront probablement dans .NET Standard et, à partir de là, dans toutes les autres implémentations de la bibliothèque de classes de base.

12
Mathieu Renda

Ce sont les solutions les plus faciles.

  1. Par index de

    string title = "STRING";
    
    if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
    {
        // contains 
    }
    
  2. En changeant de cas

    string title = "STRING";
    
    bool contains = title.ToLower().Contains("string")
    
  3. Par regex

    Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
    
11
LAV VISHWAKARMA

Juste comme ça:

string s="AbcdEf";
if(s.ToLower().Contains("def"))
{
    Console.WriteLine("yes");
}
10
cdytoby

La méthode InStr de VisualBasic Assembly est la meilleure solution si vous avez des problèmes d'internationalisation (ou que vous pouvez le réimplémenter). En y regardant, dotNeetPeek montre qu'il ne tient pas seulement compte des majuscules et des minuscules, mais également du type kana et des caractères pleine largeur et demi-largeur (surtout pour les langues asiatiques, bien qu'il existe également des versions pleine largeur de l'alphabet romain ). Je saute quelques détails, mais vérifiez la méthode privée InternalInStrText:

private static int InternalInStrText(int lStartPos, string sSrc, string sFind)
{
  int num = sSrc == null ? 0 : sSrc.Length;
  if (lStartPos > num || num == 0)
    return -1;
  if (sFind == null || sFind.Length == 0)
    return lStartPos;
  else
    return Utils.GetCultureInfo().CompareInfo.IndexOf(sSrc, sFind, lStartPos, CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth);
}
10
Casey

Je sais que ce n'est pas le C #, mais dans le framework (VB.NET) il y a déjà une telle fonction

Dim str As String = "UPPERlower"
Dim b As Boolean = InStr(str, "UpperLower")

Variante C #:

string myString = "Hello World";
bool contains = Microsoft.VisualBasic.Strings.InStr(myString, "world");
10
serhio

Utilisez ceci:

string.Compare("string", "STRING", new System.Globalization.CultureInfo("en-US"), System.Globalization.CompareOptions.IgnoreCase);
9
mr.martan

Utiliser un RegEx est un moyen simple de faire ceci:

Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
6
Stend

Ceci est assez similaire à d'autres exemples ici, mais j'ai décidé de simplifier énum en premier, car d'autres alternatives ne sont normalement pas nécessaires. Voici mon exemple:

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

Et l'utilisation est quelque chose comme:

if( "main String substring".Contains("SUBSTRING", true) )
....
5
TarmoPikaro

Le truc ici est de chercher la chaîne en ignorant la casse, mais de la garder exactement la même (avec la même casse).

 var s="Factory Reset";
 var txt="reset";
 int first = s.IndexOf(txt, StringComparison.InvariantCultureIgnoreCase) + txt.Length;
 var subString = s.Substring(first - txt.Length, txt.Length);

La sortie est "Reset"

2
Mr.B

Vous pouvez utiliser la fonction string.indexof (). Ce sera insensible à la casse

2
Okan SARICA
if ("strcmpstring1".IndexOf(Convert.ToString("strcmpstring2"), StringComparison.CurrentCultureIgnoreCase) >= 0){return true;}else{return false;}
2
Tamilselvan K
public static class StringExtension
{
    #region Public Methods

    public static bool ExContains(this string fullText, string value)
    {
        return ExIndexOf(fullText, value) > -1;
    }

    public static bool ExEquals(this string text, string textToCompare)
    {
        return text.Equals(textToCompare, StringComparison.OrdinalIgnoreCase);
    }

    public static bool ExHasAllEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index]) == false) return false;
        return true;
    }

    public static bool ExHasEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index])) return true;
        return false;
    }

    public static bool ExHasNoEquals(this string text, params string[] textArgs)
    {
        return ExHasEquals(text, textArgs) == false;
    }

    public static bool ExHasNotAllEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index])) return false;
        return true;
    }

    /// <summary>
    /// Reports the zero-based index of the first occurrence of the specified string
    /// in the current System.String object using StringComparison.InvariantCultureIgnoreCase.
    /// A parameter specifies the type of search to use for the specified string.
    /// </summary>
    /// <param name="fullText">
    /// The string to search inside.
    /// </param>
    /// <param name="value">
    /// The string to seek.
    /// </param>
    /// <returns>
    /// The index position of the value parameter if that string is found, or -1 if it
    /// is not. If value is System.String.Empty, the return value is 0.
    /// </returns>
    /// <exception cref="ArgumentNullException">
    /// fullText or value is null.
    /// </exception>
    public static int ExIndexOf(this string fullText, string value)
    {
        return fullText.IndexOf(value, StringComparison.OrdinalIgnoreCase);
    }

    public static bool ExNotEquals(this string text, string textToCompare)
    {
        return ExEquals(text, textToCompare) == false;
    }

    #endregion Public Methods
}
0
Final Heaven

si vous voulez vérifier si votre chaîne passée est dans la chaîne, il existe une méthode simple pour cela.

string yourStringForCheck= "abc";
string stringInWhichWeCheck= "Test abc abc";

bool isContaines = stringInWhichWeCheck.ToLower().IndexOf(yourStringForCheck.ToLower()) > -1;

This boolean value will return if string contains or not
0
shaishav shukla

Pour compléter la réponse ici, vous pouvez créer une méthode d’extension de chaîne afin de la rendre plus conviviale:

    public static bool ContainsIgnoreCase(this string paragraph, string Word)
    {
        return new CultureInfo("en-US").CompareInfo.IndexOf(paragraph, Word, CompareOptions.IgnoreCase) >= 0;
    }
0
Melbourne Developer