c# - net - Case insensitive 'Contains(string)'




vb net string contains case insensitive (16)

Solo .NET Core 2.0+ (al momento)

.NET Core ha avuto un paio di metodi per risolvere questo problema dalla versione 2.0:

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

Esempio:

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

Col tempo, probabilmente si faranno strada nello standard .NET e, da lì, in tutte le altre implementazioni della Base Class Library.

C'è un modo per rendere il seguente ritorno vero?

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

Non sembra esserci un sovraccarico che mi permetta di impostare la distinzione tra maiuscole e minuscole. Attualmente li UPPERCASE entrambi, ma questo è semplicemente sciocco (con cui mi riferisco ai problemi i18n che hanno un involucro alto e basso).

AGGIORNARE
Questa domanda è antica e da allora mi sono reso conto che ho chiesto una risposta semplice per un argomento davvero vasto e difficile se ti interessa investigarlo completamente.
Per la maggior parte dei casi, in base al codice in lingua inglese, this risposta sarà sufficiente. Sospetto che la maggior parte della gente che viene qui cada in questa categoria è la risposta più popolare.
This risposta, tuttavia, fa emergere il problema intrinseco che non possiamo confrontare il maiuscolo / minuscolo del testo fino a quando non sappiamo che entrambi i testi sono la stessa cultura e sappiamo che cos'è questa cultura. Questa è forse una risposta meno popolare, ma penso che sia più corretta ed è per questo che l'ho contrassegnata come tale.


È possibile utilizzare il metodo String.IndexOf e passare StringComparison.OrdinalIgnoreCase come tipo di ricerca da utilizzare:

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

Ancora meglio sta definendo un nuovo metodo di estensione per la stringa:

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

Nota, quella propagazione nulla ?. è disponibile da C # 6.0 (VS 2015), per le versioni precedenti

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

USO:

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

Il metodo InStr dall'assembly VisualBasic è il migliore se si ha una preoccupazione per l'internazionalizzazione (o si potrebbe reimplementarla). Guardando in esso, dotNeetPeek mostra che non solo tiene conto di maiuscole e minuscole, ma anche di caratteri kana e di caratteri pieni e semi-larghi (principalmente rilevanti per le lingue asiatiche, sebbene ci siano anche versioni a larghezza intera dell'alfabeto romano) ). Sto saltando alcuni dettagli, ma controlla il metodo privato 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);
}

Il trucco qui è cercare la stringa, ignorando la custodia, ma per mantenerla esattamente la stessa (con lo stesso caso).

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

L'uscita è "Ripristina"


L'uso di una RegEx è un modo semplice per farlo:

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

La classe StringExtension è la soluzione da seguire, ho combinato un paio di post sopra per dare un esempio di codice completo:

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

Proprio come questo:

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

Puoi sempre alzare o abbassare le stringhe prima.

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

Oops, ho appena visto quell'ultima parte. Un confronto senza distinzione tra maiuscole e minuscole avrebbe * probabilmente * lo stesso effetto, e se le prestazioni non sono un problema, non vedo un problema con la creazione di copie maiuscole e il confronto di quelle. Potrei giurare che una volta ho visto un confronto insensibile al caso ...


Queste sono le soluzioni più facili.

  1. Per indice di

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

    string title = "STRING";
    
    bool contains = title.ToLower().Contains("string")
    
  3. Di Regex

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

Questo è abbastanza simile ad un altro esempio qui, ma ho deciso di semplificare enum per bool, primario perché normalmente non sono necessarie altre alternative. Ecco il mio esempio:

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

E l'utilizzo è qualcosa come:

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

So che questo non è il C #, ma nel framework (VB.NET) esiste già una tale funzione

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

Soluzione alternativa con Regex:

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

Avviso

Come ha sottolineato @cHao nel suo commento, ci sono degli scenari che causeranno che questa soluzione restituisca risultati errati. Assicurati di sapere cosa stai facendo prima di implementare questa soluzione a caso.


Usa questo:

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

se si desidera verificare se la stringa passata è in stringa, esiste un metodo semplice.

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

OrdinalIgnoreCase, CurrentCultureIgnoreCase o InvariantCultureIgnoreCase?

Poiché questo manca, ecco alcuni consigli su quando utilizzare quale:

dos

  • Usa StringComparison.OrdinalIgnoreCase per i confronti come predefinito sicuro per la corrispondenza stringa indipendente dalla cultura.
  • Usa confronti StringComparison.OrdinalIgnoreCase per aumentare la velocità.
  • Utilizzare le operazioni stringa StringComparison.CurrentCulture-based quando si visualizza l'output per l'utente.
  • Cambiare l'uso corrente delle operazioni stringa sulla base della cultura invariabile per utilizzare StringComparison.Ordinal o StringComparison.OrdinalIgnoreCase non linguistico quando il confronto è
    linguisticamente irrilevante (simbolico, per esempio).
  • Utilizzare ToUpperInvariant anziché ToLowerInvariant durante la normalizzazione delle stringhe per il confronto.

cosa non fare

  • Utilizzare gli overload per le operazioni sulle stringhe che non specificano esplicitamente o implicitamente il meccanismo di comparazione delle stringhe.
  • Usa stringa StringComparison.InvariantCulture
    operazioni nella maggior parte dei casi; una delle poche eccezioni sarebbe
    persistenti dati linguisticamente significativi ma culturalmente-agnostici.

Sulla base di queste regole dovresti usare:

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

mentre [YourDecision] dipende dalle raccomandazioni di cui sopra.

collegamento di origine: http://msdn.microsoft.com/en-us/library/ms973919.aspx


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




case-insensitive