Hoofdlettergevoelig ‘Contains(string)’

Is er een manier om het volgende resultaat waar te maken?

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

Er lijkt geen overbelasting te zijn waardoor ik de hoofdlettergevoeligheid kan instellen. Momenteel HOOFDLETTERS ze allebei, maar dat is gewoon dom (waarmee ik verwijs naar de i18nproblemen die worden geleverd met op- en neerwaartse behuizing).

UPDATE
Deze vraag is oud en sindsdien realiseer ik me dat ik om een eenvoudig antwoord heb gevraagd voor een heel uitgebreid en moeilijk onderwerp als je het volledig wilt onderzoeken.
In de meeste gevallen zal in eentalige, Engelse codebases ditantwoord voldoende zijn. Ik vermoed dat omdat de meeste mensen die hier komen in deze categorie vallen, dit het meest populaire antwoord is.
Ditantwoord brengt echter het inherente probleem met zich mee dat we tekst niet hoofdlettergevoelig kunnen vergelijken totdat we weten dat beide teksten dezelfde cultuur hebben en we weten wat die cultuur is. Dit is misschien een minder populair antwoord, maar ik denk dat het juister is en daarom heb ik het als zodanig gemarkeerd.


Antwoord 1, autoriteit 100%

Om te testen of de tekenreeks paragraphde tekenreeks wordbevat (bedankt @QuarterMeister)

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

Waar culturede instantie is van CultureInfodie de taal beschrijft waarin de tekst is geschreven.

Deze oplossing is transparant over de definitie van hoofdletterongevoeligheid, die taalafhankelijk is. De Engelse taal gebruikt bijvoorbeeld de tekens ien ivoor de hoofdletters en kleine letters van de negende letter, terwijl de Turkse taal deze tekens gebruikt voor de elfde en twaalfde lettersvan het 29-letterlange alfabet. De Turkse hoofdletterversie van ‘i’ is het onbekende teken ‘İ’.

Dus de strings TINen TINzijn hetzelfde woord in het Engels, maar verschillende woorden in het Turks. Zoals ik begrijp, betekent de ene ‘geest’ en de andere is een onomatopee-woord. (Turken, corrigeer me als ik het mis heb, of stel een beter voorbeeld voor)

Samenvattend: je kunt de vraag ‘zijn deze twee strings hetzelfde, maar in verschillende gevallen’ beantwoorden als je weet in welke taal de tekst is. Als je het niet weet, moet je een gok wagen. Gezien de hegemonie van Engels in software, zou je waarschijnlijk je toevlucht moeten nemen tot CultureInfo.InvariantCulture, omdat het op bekende manieren verkeerd zal zijn.


Antwoord 2, autoriteit 91%

Je zou de String.IndexOf-methodeen geef StringComparison.OrdinalIgnoreCaseals het type zoekopdracht dat moet worden gebruikt:

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

Nog beter is het definiëren van een nieuwe extensiemethode voor string:

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

Merk op dat null-propagatie?.is beschikbaar sinds C# 6.0 (VS 2015), voor oudere versies gebruik

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

GEBRUIK:

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

Antwoord 3, autoriteit 16%

U kunt IndexOf()als volgt gebruiken:

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

Aangezien 0 (nul) een index kan zijn, controleer je tegen -1.

MSDN

De op nul gebaseerde indexpositie van waarde als die tekenreeks wordt gevonden, of -1
als het niet is. Als de waarde String.Empty is, is de geretourneerde waarde 0.


Antwoord 4, autoriteit 10%

Alternatieve oplossing met Regex:

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

Antwoord 5, autoriteit 6%

.NET Core 2.0+ (inclusief .NET 5.0+)

.NET Core heeft sinds versie 2.0 een paar methoden om hiermee om te gaan:

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

Voorbeeld:

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

Het maakt nu officieel deel uit van de .NET Standard 2.1, en dus onderdeel van alle implementaties van de Base Class Library die deze versie van de standaard (of een hogere) implementeren.


Antwoord 6, autoriteit 6%

Je kunt altijd eerst de strings omhoog of omlaag zetten.

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

Oeps, zag net dat laatste stukje. Een hoofdletterongevoelige vergelijking zou *waarschijnlijk*toch hetzelfde doen, en als prestatie geen probleem is, zie ik geen probleem om kopieën in hoofdletters te maken en die te vergelijken. Ik had kunnen zweren dat ik ooit een hoofdletterongevoelige vergelijking heb gezien…


Antwoord 7, autoriteit 4%

Een probleem met het antwoord is dat het een uitzondering genereert als een string null is. Je kunt dat als controle toevoegen, zodat het niet:

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

Antwoord 8, autoriteit 3%

StringExtension-klasse is de beste keuze, ik heb een aantal van de bovenstaande berichten gecombineerd om een compleet codevoorbeeld te geven:

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

Antwoord 9, autoriteit 2%

Dit is duidelijk en eenvoudig.

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

Antwoord 10, autoriteit 2%

OrdinalIgnoreCase, CurrentCultureIgnoreCase of InvariantCultureIgnoreCase?

Aangezien dit ontbreekt, volgen hier enkele aanbevelingen over wanneer u welke moet gebruiken:

Do’s

  • Gebruik StringComparison.OrdinalIgnoreCasevoor vergelijkingen
    als uw veilige standaard voor cultuur-agnostische string-matching.
  • Gebruik StringComparison.OrdinalIgnoreCasevergelijkingen
    voor meer snelheid.
  • Gebruik StringComparison.CurrentCulture-basedtekenreeksbewerkingen
    bij het weergeven van de uitvoer aan de gebruiker.
  • Schakel huidig gebruik van stringbewerkingen om op basis van de invariant
    Cultuur om de niet-linguïstische StringComparison.Ordinalof StringComparison.OrdinalIgnoreCasewanneer de vergelijking is
    taalkundig irrelevant (bijvoorbeeld symbolisch).
  • Gebruik ToUpperInvariantin plaats van ToLowerInvariantwanneer
    normaliseren van snaren voor vergelijking.

Don’ts

  • Gebruik overbelastingen voor tekenreeksbewerkingen die niet expliciet zijn
    of impliciet het reeksvergelijkingsmechanisme opgeven.
  • Gebruik StringComparison.InvariantCulture-Based String
    operaties in de meeste gevallen; een van de weinige uitzonderingen zou zijn
    aanhoudende linguistisch zinvolle maar cultureel-agnostische gegevens.

Op basis van deze regels moet u gebruiken:

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

overwegende dat [YourDecision] afhangt van de aanbevelingen van boven.

Link of Source: http://msdn.microsoft.com/en-us/library/ms973919 .aspx


Antwoord 11, Autoriteit 2%

Dit zijn de gemakkelijkste oplossingen.

  1. per index van

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

    te wijzigen

    string title = "STRING";
    bool contains = title.ToLower().Contains("string")
    
  3. door RGEX

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

Antwoord 12

Zo eenvoudig en werkt

title.ToLower().Contains("String".ToLower())

Antwoord 13

Zo:

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

Antwoord 14

Ik weet dat dit niet de C# is, maar in het framework (VB.NET) is er al zo’n functie

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

C#-variant:

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

Antwoord 15

De InStr-methode van de VisualBasic-assembly is de beste als u zich zorgen maakt over internationalisering (of als u deze opnieuw zou kunnen implementeren). Als we daarin dotNeetPeek bekijken, zien we dat het niet alleen hoofdletters en kleine letters bevat, maar ook kana-type en tekens op volledige versus halve breedte (meestal relevant voor Aziatische talen, hoewel er ook volledige versies van het Romeinse alfabet zijn ). Ik sla enkele details over, maar bekijk de privémethode 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);
}

Antwoord 16

Gebruik dit:

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

Antwoord 17

U kunt een stringvergelijkingsparameter gebruiken (beschikbaar vanaf .net 2.1 en hoger) String.Contains-methode.

public bool Contains (string value, StringComparison comparisonType);

Voorbeeld:

string title = "ASTRINGTOTEST";
title.Contains("string", StringComparison.InvariantCultureIgnoreCase);

Antwoord 18

Dit lijkt veel op andere voorbeelden hier, maar ik heb besloten om enum te vereenvoudigen tot bool, primair omdat andere alternatieven normaal gesproken niet nodig zijn. Hier is mijn voorbeeld:

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

En het gebruik is zoiets als:

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

Antwoord 19

Het gebruik van een regex is een rechte manier om dit te doen:

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

Antwoord 20

Alleen om hier op het antwoord te bouwen, kunt u een string-uitbreidingsmethode maken om dit een beetje meer gebruiksvriendelijker te maken:

   public static bool ContainsIgnoreCase(this string paragraph, string word)
    {
        return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
    }

Antwoord 21

Als u wilt controleren of uw doorgegeven string in reeks is, is er daarvoor een eenvoudige methode.

string yourStringForCheck= "abc";
string stringInWhichWeCheck= "Test abc abc";
bool isContained = stringInWhichWeCheck.ToLower().IndexOf(yourStringForCheck.ToLower()) > -1;

Deze Booleaanse waarde zal terugkeren als de tekenreeks is ingesloten of niet


Antwoord 22

vergelijkbaar met eerdere antwoorden (met behulp van een extensie-methode) maar met twee eenvoudige nullcontroles (C # 6.0 en hoger):

public static bool ContainsIgnoreCase(this string source, string substring)
{
    return source?.IndexOf(substring ?? "", StringComparison.OrdinalIgnoreCase) >= 0;
}

Als bron null is, retourneert u false (via null-propagation-operator?)

Als substring null is, behandel dan als een lege snaar en retourneren true (via null-coalescing operator ??)

De stringcomparison kan uiteraard als parameter worden verzonden indien nodig.


Antwoord 23

if ("strcmpstring1".IndexOf(Convert.ToString("strcmpstring2"), StringComparison.CurrentCultureIgnoreCase) >= 0){return true;}else{return false;}

Antwoord 24

U kunt string.indexof ()-functie gebruiken. Dit zal geval zijn ongevoelig


Antwoord 25

De truc hier is om te zoeken naar de string, het negeren van de zaak, maar om het precies hetzelfde te houden (met dezelfde zaak).

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

Uitgang is “RESET”


Antwoord 26

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
}

Antwoord 27

Gebaseerd op de bestaande antwoorden en op de documentatie van Bevat Methode zou ik aanbevelen aan de oprichting van de volgende extensie die ook voor de Correctiekaartjes zorgt:

public static class VStringExtensions 
{
    public static bool Contains(this string source, string toCheck, StringComparison comp) 
    {
        if (toCheck == null) 
        {
            throw new ArgumentNullException(nameof(toCheck));
        }
        if (source.Equals(string.Empty)) 
        {
            return false;
        }
        if (toCheck.Equals(string.Empty)) 
        {
            return true;
        }
        return source.IndexOf(toCheck, comp) >= 0;
    }
}

Antwoord 28

eenvoudige manier voor newbie:

title.ToLower().Contains("string");//of course "string" is lowercase.

Other episodes