c# .contains culture - Insensible à la casse 'Contient (string)'




12 Answers

Pour tester si le paragraph chaîne contient le word chaîne (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 en ce qui concerne 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 ne pouvez répondre à la question "ces deux chaînes sont-elles identiques, mais dans des cas différents" si vous savez dans quelle langue se trouve le texte . Si vous ne savez pas, vous devrez prendre une punt. Compte tenu de l'hégémonie anglaise des logiciels, vous devriez probablement recourir à CultureInfo.InvariantCulture , car ce sera une erreur de façon familière.

invariant net

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 des problèmes de développement qui vont de haut en bas).

METTRE À JOUR
Cette question est ancienne et depuis lors, je réalise que je vous ai demandé une réponse simple à un sujet très vaste et difficile si vous souhaitez approfondir votre recherche.
Dans la plupart des cas, dans les bases de code anglais unilingues, this réponse suffira. Je soupçonne, car la plupart des gens qui viennent ici tombent dans cette catégorie, c'est la réponse la plus populaire.
This réponse soulève toutefois le problème inhérent que nous ne pouvons pas comparer un texte insensible à la casse tant que nous ne savons pas que les deux textes appartiennent à 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.




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

Position d'index de base zéro de la valeur 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.




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

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

Oops, je viens de voir ce dernier morceau. Une comparaison insensible à la casse * ferait * probablement * la même chose de toute façon, 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 ...




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;
    }
}



OrdinalIgnoreCase, CurrentCultureIgnoreCase ou InvariantCultureIgnoreCase?

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

Dos

  • Utilisez StringComparison.OrdinalIgnoreCase pour les comparaisons comme valeur par défaut sûre pour la correspondance de chaînes StringComparison.OrdinalIgnoreCase de la culture.
  • Utilisez les comparaisons StringComparison.OrdinalIgnoreCase pour augmenter la vitesse.
  • Utilisez des opérations de chaîne StringComparison.CurrentCulture-based lors de l'affichage du résultat à l'utilisateur.
  • Basculez l'utilisation actuelle des opérations de chaîne basées sur la culture invariante pour utiliser StringComparison.Ordinal ou StringComparison.OrdinalIgnoreCase non linguistique lorsque la comparaison est effectuée.
    linguistiquement non pertinent (symbolique, par exemple).
  • Utilisez ToUpperInvariant plutôt que ToLowerInvariant lors de la normalisation de chaînes pour la comparaison.

À ne pas faire

  • Utilisez des surcharges pour les opérations sur les chaînes qui ne spécifient pas explicitement ou implicitement le mécanisme de comparaison des chaînes.
  • Utiliser StringComparison.InvariantCulture 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




La méthode InStr de l'assembly VisualBasic est la meilleure solution si vous avez des problèmes d'internationalisation (ou si vous pouvez le réimplémenter). Si on y regarde, dotNeetPeek montre qu'il ne tient pas seulement compte des majuscules et des minuscules, mais également du type kana et des caractères pleine par rapport à la moitié de la largeur (surtout pour les langues asiatiques, bien qu'il existe aussi 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);
}



Utilisez ceci:

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



Utiliser un RegEx est un moyen simple de faire ceci:

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



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);
    



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




.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 entreront probablement dans .NET Standard et, à partir de là, dans toutes les autres implémentations de la bibliothèque de classes de base.




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



Related