Vraag Hoofdletterongevoelig 'Bevat (tekenreeks)'


Is er een manier om de volgende terugkeer waar te maken?

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

Er lijkt geen overbelasting te zijn die me in staat stelt de hoofdlettergevoeligheid in te stellen. Momenteel HAAT IK ze allebei TOPPERCASE, maar dat is gewoon dom (waarmee ik verwijs naar de i18n problemen die gepaard gaan met op en neer omhulsel).

BIJWERKEN
Deze vraag is oud en sindsdien realiseer ik me dat ik om een ​​eenvoudig antwoord heb gevraagd voor een echt enorm en moeilijk onderwerp als je het volledig wilt onderzoeken.
Voor de meeste gevallen, in eentalige, Engelse codebases deze antwoord zal volstaan. Ik vermoed dat de meeste mensen die hier komen in deze categorie vallen, dit is het meest populaire antwoord.
Deze Het antwoord noemt echter het inherente probleem dat we de tekst niet ongevoelig kunnen vergelijken totdat we weten dat beide teksten dezelfde cultuur zijn 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.


2416
2018-01-14 21:39


oorsprong


antwoorden:


Om te testen of de string paragraph bevat de string word (bedankt @QuarterMeister)

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

Waar culture is de instantie van CultureInfo beschrijft de taal waarin de tekst is geschreven.

Deze oplossing is transparant over de definitie van hoofd-ongevoeligheid, die taalafhankelijk is. De Engelse taal gebruikt bijvoorbeeld de tekens I en i voor de hoofdletters en kleine letters van de negende letter, terwijl de Turkse taal deze tekens gebruikt voor de elfde en twaalfde letters van zijn 29 letter-lange alfabet. De Turkse hoofdletterversie van 'i' is het onbekende karakter 'İ'.

Dus de snaren tin en TIN zijn hetzelfde woord in Engels, maar andere woorden in het Turks. Zoals ik begrijp, betekent de één 'geest' en de andere is een woord van de onomatopee. (Turken, corrigeer me als ik ongelijk heb, of stel een beter voorbeeld voor)

Samengevat, u kunt alleen de vraag beantwoorden 'zijn deze twee reeksen hetzelfde, maar in verschillende gevallen' als je weet in welke taal de tekst staat. Als je het niet weet, moet je een punter nemen. Gezien de hegemonie van het Engels in software, zou u waarschijnlijk zijn toevlucht nemen tot CultureInfo.InvariantCulture, omdat het op bekende manieren niet klopt.


1083
2018-03-17 18:22



Je zou de kunnen gebruiken String.IndexOf-methode en ga voorbij StringComparison.OrdinalIgnoreCase als het type zoekactie om te gebruiken:

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

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

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

Let daar op nulverspreiding  ?. is beschikbaar sinds C # 6.0 (VS 2015), voor oudere versies gebruiken

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

GEBRUIK:

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

2356
2018-01-14 21:44



Je kunt gebruiken IndexOf() soortgelijk:

string title = "STRING";

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

Omdat 0 (nul) een index kan zijn, controleert u 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 retourwaarde 0.


203
2018-01-14 21:48



Alternatieve oplossing met Regex:

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

Merk op

Zoals @cHao in zijn commentaar heeft opgemerkt, zijn er scenario's die ervoor zorgen dat deze oplossing onjuiste resultaten oplevert. Zorg ervoor dat je weet wat je doet voordat je deze oplossing lukraak implementeert.


115
2017-07-28 17:18



Je kunt altijd eerst de snaren omhoog of omlaag brengen.

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

Oeps, heb net dat laatste stukje gezien. Een gevalongevoelige vergelijking zou *waarschijnlijk* doe hoe dan ook hetzelfde, en als de prestaties geen probleem zijn, zie ik geen probleem met het maken van kopieën in hoofdletters en het vergelijken daarvan. Ik had kunnen zweren dat ik ooit een gevalongevoelige vergelijking heb gezien ...


62
2018-01-14 21:42



Een probleem met het antwoord is dat het een uitzondering oplevert als een reeks nul is. U kunt dit toevoegen als een controle, 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;
} 

48
2017-12-07 21:11



StringExtension klasse is de weg vooruit, ik heb een paar van de bovenstaande berichten gecombineerd om een ​​volledig 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;
    }
}

32
2017-11-18 16:48