Utilizzo di C # per verificare se stringa contiene una stringa nella matrice di stringhe


290

Voglio usare C # per verificare se un valore di stringa contiene una parola in un array di stringhe. Per esempio,

string stringToCheck = "text1text2text3";

string[] stringArray = { "text1", "someothertext", etc... };

if(stringToCheck.contains stringArray) //one of the items?
{

}

Come posso verificare se il valore di stringa per 'stringToCheck' contiene una parola nell'array?


1
Questo blog confronta numerose tecniche per verificare se una stringa contiene una stringa: blogs.davelozinski.com/curiousconsultant/…
Robert Harvey

Risposte:


145

Ecco come puoi farlo:

string stringToCheck = "text1";
string[] stringArray = { "text1", "testtest", "test1test2", "test2text1" };
foreach (string x in stringArray)
{
    if (stringToCheck.Contains(x))
    {
        // Process...
    }
}

AGGIORNAMENTO: Forse stai cercando una soluzione migliore .. fai riferimento alla risposta di @Anton Gogolev di seguito che fa uso di LINQ.


3
Grazie, ho modificato il codice in: if (stringToCheck.Contains (s)) e ha funzionato.
Theomax,

5
Ho fatto if (stringArray.Contains (stringToCheck)) e funziona benissimo, grazie.
Tamara JQ,

68
Non usare questa risposta invece usa LINQ
AlexC

11
Piccola nota per le persone che non vedono il metodo Contiene sull'array di stringhe: Verifica se hai un "using System.Linq;" spazio dei nomi nel tuo file di codice :)
Sudhanshu Mishra,

5
Linq non è sempre disponibile nei software legacy.
William Morrison,

843

Ecco come:

if(stringArray.Any(stringToCheck.Contains))
/* or a bit longer: (stringArray.Any(s => stringToCheck.Contains(s))) */

Verifica se stringToCheckcontiene una delle sottostringhe da stringArray. Se vuoi assicurarti che contenga tutte le sottostringhe, cambia Anyin All:

if(stringArray.All(stringToCheck.Contains))

116
Nota per sé: linq è incredibile, linq è incredibile, linq è incredibile! Devo iniziare a usare linq.
Fredrik Johansson,

2
@Spooks Linq To Objects (utilizzato nel controllo delle stringhe della risposta) può essere utilizzato tramite LinqBridge su .NET 2.0 albahari.com/nutshell/linqbridge.aspx
David Rettenbacher

1
come faresti con l'invarianza del caso?
Offler l'

14
@Offler SarebbestringArray.Any(s => s.IndexOf(stringToCheck, StringComparison.CurrentCultureIgnoreCase) > -1)
Anton Gogolev l'

2
come ottenere quale elemento nell'array corrisponde?
ibubi,

44

Prova questo:

Non è necessario utilizzare LINQ

if (Array.IndexOf(array, Value) >= 0)
{
    //Your stuff goes here
}

Bello! E quale vantaggio Linq potrebbe avere su Array.IndexOf ??
Heckflosse_230,

21
Questo non risolve affatto la domanda. IndexOf ti dice se una matrice contiene una corrispondenza esatta per una stringa, la domanda originale è se una stringa contiene una di una matrice di stringhe, che Linq gestisce facilmente.
NetMage,

So che questo commento è in ritardo, ma solo per coloro che non lo sanno, una stringa è un array di caratteri, quindi i tipi di stringa contengono un metodo IndexOf ... quindi @NetMage è una possibile soluzione.
Blacky Wolf,

3
@ Black Wolf, hai letto la domanda? Array.IndexOf ti dice se un array contiene un valore, l'OP voleva sapere se un valore contiene un membro di un array, esattamente l'opposto di questa risposta. È possibile utilizzare String.IndexOf con Linq: stringArray.Any(w => stringToCheck.IndexOf(w) >= 0)ma la risposta Linq utilizzando String.Contains ha più senso, poiché è esattamente ciò che viene richiesto.
NetMage,

40

Usa il metodo linq:

stringArray.Contains(stringToCheck)

4
Nota che Contiene è un metodo di estensione e devi farlousing System.Linq;
isHuman il

11
Questa risposta è arretrata rispetto alla domanda.
NetMage,

2
In che modo questa risposta è stata votata così tante volte? 5 anni dopo che la domanda è stata posta e la soluzione è sostanzialmente invertita rispetto alla domanda.
Fus Ro Dah,

1
forse basta invertire i nomi delle variabili andrà bene?
Jean-François Fabre

8

Modo più semplice e di esempio.

  bool bol=Array.Exists(stringarray,E => E == stringtocheck);

meglio è stringarray.Exists (entity => entity == stringtocheck)
Marcel Grüger

Penso che non puoi chiamare il metodo esiste direttamente dall'array di stringhe. Il metodo Exists può usare direttamente per l'elenco <T>. Quindi dovresti usare il metodo statico array.exist <T> per l'array string.check here => msdn.microsoft.com/en- us / library / yw84x8be (v = vs.110) .aspx
Jze il

6
string strName = "vernie";
string[] strNamesArray = { "roger", "vernie", "joel" };

if (strNamesArray.Any(x => x == strName))
{
   // do some action here if true...
}

2
Non penso che questo sia ciò che la domanda sta ponendo.
Pang

5

Qualcosa del genere forse:

string stringToCheck = "text1text2text3";
string[] stringArray = new string[] { "text1" };
if (Array.Exists<string>(stringArray, (Predicate<string>)delegate(string s) { 
    return stringToCheck.IndexOf(s, StringComparison.OrdinalIgnoreCase) > -1; })) {
    Console.WriteLine("Found!");
}

Questa è una soluzione migliore, poiché è un controllo di sottostringa rispetto alle parole in un elenco anziché un controllo di corrispondenza esatto.
Roy B

Bella risposta, ma wow che è difficile da leggere rispetto al moderno C # anche senza Linq; inoltre, String.Containspotrebbe essere meglio che a String.IndexOfmeno che tu non voglia ignorare il caso, dal momento che Microsoft ha dimenticato due argomenti che String.Containsdevi scrivere tu. Considera:Array.Exists(stringArray, s => stringToCheck.IndexOf(s, StringComparison.OrdinalIgnoreCase) > -1)
NetMage il

3

L'uso di Linq e del gruppo di metodi sarebbe il modo più rapido e compatto per farlo.

var arrayA = new[] {"element1", "element2"};
var arrayB = new[] {"element2", "element3"};
if (arrayB.Any(arrayA.Contains)) return true;

3

Puoi definire i tuoi metodi string.ContainsAny()e quelli string.ContainsAll(). Come bonus, ho anche lanciato un string.Contains()metodo che consente un confronto senza distinzione tra maiuscole e minuscole, ecc.

public static class Extensions
{
    public static bool Contains(this string source, string value, StringComparison comp)
    {
        return source.IndexOf(value, comp) > -1;
    }

    public static bool ContainsAny(this string source, IEnumerable<string> values, StringComparison comp = StringComparison.CurrentCulture)
    {
        return values.Any(value => source.Contains(value, comp));
    }

    public static bool ContainsAll(this string source, IEnumerable<string> values, StringComparison comp = StringComparison.CurrentCulture)
    {
        return values.All(value => source.Contains(value, comp));
    }
}

Puoi testarli con il seguente codice:

    public static void TestExtensions()
    {
        string[] searchTerms = { "FOO", "BAR" };
        string[] documents = {
            "Hello foo bar",
            "Hello foo",
            "Hello"
        };

        foreach (var document in documents)
        {
            Console.WriteLine("Testing: {0}", document);
            Console.WriteLine("ContainsAny: {0}", document.ContainsAny(searchTerms, StringComparison.OrdinalIgnoreCase));
            Console.WriteLine("ContainsAll: {0}", document.ContainsAll(searchTerms, StringComparison.OrdinalIgnoreCase));
            Console.WriteLine();
        }
    }

2

Uso quanto segue in un'applicazione console per verificare la presenza di argomenti

var sendmail = args.Any( o => o.ToLower() == "/sendmail=true");

2

Vorrei usare Linq ma può ancora essere fatto attraverso:

new[] {"text1", "text2", "etc"}.Contains(ItemToFind);

1

Provare:

String[] val = { "helloword1", "orange", "grape", "pear" };
String sep = "";
string stringToCheck = "word1";

bool match = String.Join(sep,val).Contains(stringToCheck);
bool anothermatch = val.Any(s => s.Contains(stringToCheck));

1

È anche possibile fare la stessa cosa di Anton Gogolev suggerisce di verificare se qualsiasi elemento in stringArray1corrisponde qualsiasi elemento in stringArray2:

if(stringArray1.Any(stringArray2.Contains))

E allo stesso modo tutti gli elementi in stringArray1 corrispondono a tutti gli elementi in stringArray2:

if(stringArray1.All(stringArray2.Contains))


0

prova questo, qui l'esempio: per verificare se il campo contiene una delle parole nell'array. Per verificare se il campo (someField) contiene una delle parole dell'array.

String[] val = { "helloword1", "orange", "grape", "pear" };   

Expression<Func<Item, bool>> someFieldFilter = i => true;

someFieldFilter = i => val.Any(s => i.someField.Contains(s));

0
public bool ContainAnyOf(string word, string[] array) 
    {
        for (int i = 0; i < array.Length; i++)
        {
            if (word.Contains(array[i]))
            {
                return true;
            }
        }
        return false;
    }

0

Ho usato un metodo simile a IndexOf di Maitrey684 e al ciclo foreach di Theomax per creare questo. (Nota: le prime 3 righe "stringa" sono solo un esempio di come è possibile creare un array e ottenerlo nel formato corretto).

Se si desidera confrontare 2 matrici, saranno delimitate da punti e virgola, ma l'ultimo valore non ne avrà uno dopo. Se aggiungi un punto e virgola alla forma di stringa dell'array (ovvero a; b; c diventa a; b; c;), puoi abbinare usando "x;" indipendentemente dalla posizione in cui si trova:

bool found = false;
string someString = "a-b-c";
string[] arrString = someString.Split('-');
string myStringArray = arrString.ToString() + ";";

foreach (string s in otherArray)
{
    if (myStringArray.IndexOf(s + ";") != -1) {
       found = true;
       break;
    }
}

if (found == true) { 
    // ....
}

0
string [] lines = {"text1", "text2", "etc"};

bool bFound = lines.Any(x => x == "Your string to be searched");

bFound impostato su true se la stringa cercata è abbinata a qualsiasi elemento delle "linee" dell'array.


0

Prova questo

string stringToCheck = "text1text2text3";
string[] stringArray = new string[] { "text1" };

var t = lines.ToList().Find(c => c.Contains(stringToCheck));

Ti restituirà la riga con la prima incidenza del testo che stai cercando.


0

Se stringArraycontiene un numero elevato di stringhe di lunghezza variabile, considerare l'utilizzo di un Trie per memorizzare e cercare l'array di stringhe.

public static class Extensions
{
    public static bool ContainsAny(this string stringToCheck, IEnumerable<string> stringArray)
    {
        Trie trie = new Trie(stringArray);
        for (int i = 0; i < stringToCheck.Length; ++i)
        {
            if (trie.MatchesPrefix(stringToCheck.Substring(i)))
            {
                return true;
            }
        }

        return false;
    }
}

Ecco l'implementazione della Trieclasse

public class Trie
{
    public Trie(IEnumerable<string> words)
    {
        Root = new Node { Letter = '\0' };
        foreach (string word in words)
        {
            this.Insert(word);
        }
    }

    public bool MatchesPrefix(string sentence)
    {
        if (sentence == null)
        {
            return false;
        }

        Node current = Root;
        foreach (char letter in sentence)
        {
            if (current.Links.ContainsKey(letter))
            {
                current = current.Links[letter];
                if (current.IsWord)
                {
                    return true;
                }
            }
            else
            {
                return false;
            }
        }

        return false;
    }

    private void Insert(string word)
    {
        if (word == null)
        {
            throw new ArgumentNullException();
        }

        Node current = Root;
        foreach (char letter in word)
        {
            if (current.Links.ContainsKey(letter))
            {
                current = current.Links[letter];
            }
            else
            {
                Node newNode = new Node { Letter = letter };
                current.Links.Add(letter, newNode);
                current = newNode;
            }
        }

        current.IsWord = true;
    }

    private class Node
    {
        public char Letter;
        public SortedList<char, Node> Links = new SortedList<char, Node>();
        public bool IsWord;
    }

    private Node Root;
}

Se tutte le stringhe stringArrayhanno la stessa lunghezza, starai meglio usando solo un HashSetinvece di aTrie

public static bool ContainsAny(this string stringToCheck, IEnumerable<string> stringArray)
{
    int stringLength = stringArray.First().Length;
    HashSet<string> stringSet = new HashSet<string>(stringArray);
    for (int i = 0; i < stringToCheck.Length - stringLength; ++i)
    {
        if (stringSet.Contains(stringToCheck.Substring(i, stringLength)))
        {
            return true;
        }
    }

    return false;
}

0

Soluzione semplice, non è richiesta alcuna linq

String.Join (",", array) .Contains (Value + ",");


2
Cosa succede se uno dei valori nell'array contiene il delimitatore?
Tyler Benzing,

0
int result = Array.BinarySearch(list.ToArray(), typedString, StringComparer.OrdinalIgnoreCase);

0

Prova questo, non c'è bisogno di un loop ..

string stringToCheck = "text1";
List<string> stringList = new List<string>() { "text1", "someothertext", "etc.." };
if (stringList.Exists(o => stringToCheck.Contains(o)))
{

}

0

Per completare le risposte di cui sopra, per il controllo IgnoreCase utilizzare:

stringArray.Any(s => stringToCheck.IndexOf(s, StringComparison.CurrentCultureIgnoreCase) > -1)

C'è un modo per ottenere anche l'indice della partita con quello? Grazie.
Si8,

0

Nel mio caso, le risposte di cui sopra non hanno funzionato. Stavo verificando una stringa in un array e assegnandola a un valore booleano. Ho modificato la risposta di @Anton Gogolev e rimosso il Any()metodo e inserito stringToCheckil Contains()metodo all'interno .

bool = stringArray.Contains(stringToCheck);

0

Utilizzo dei metodi Find o FindIndex della classe Array :

if(Array.Find(stringArray, stringToCheck.Contains) != null) 
{ 
}
if(Array.FindIndex(stringArray, stringToCheck.Contains) != -1) 
{ 
}

-1

Ho usato il seguente codice per verificare se la stringa conteneva uno degli elementi nell'array di stringhe:

foreach (string s in stringArray)
{
    if (s != "")
    {
        if (stringToCheck.Contains(s))
        {
            Text = "matched";
        }
    }
}

3
Questo imposta Text = "matched"quante volte stringToCheckcontiene sottostringhe di stringArray. Potresti voler inserire un breako returndopo il compito.
Dour High Arch,

-1

Tre opzioni dimostrate. Preferisco trovare il terzo come il più conciso.

class Program {
    static void Main(string[] args) {
    string req = "PUT";
    if ((new string[] {"PUT", "POST"}).Any(s => req.Contains(s))) {
        Console.WriteLine("one.1.A");  // IS TRUE
    }
    req = "XPUT";
    if ((new string[] {"PUT", "POST"}).Any(s => req.Contains(s))) {
        Console.WriteLine("one.1.B"); // IS TRUE
    }
    req = "PUTX";
    if ((new string[] {"PUT", "POST"}).Any(s => req.Contains(s))) {
        Console.WriteLine("one.1.C");  // IS TRUE
    }
    req = "UT";
    if ((new string[] {"PUT", "POST"}).Any(s => req.Contains(s))) {
        Console.WriteLine("one.1.D"); // false
    }
    req = "PU";
    if ((new string[] {"PUT", "POST"}).Any(s => req.Contains(s))) {
        Console.WriteLine("one.1.E"); // false
    }
    req = "POST";
    if ((new string[] {"PUT", "POST"}).Any(s => req.Contains(s))) {
        Console.WriteLine("two.1.A"); // IS TRUE
    }
    req = "ASD";
    if ((new string[] {"PUT", "POST"}).Any(s => req.Contains(s))) {
        Console.WriteLine("three.1.A");  // false
    }


    Console.WriteLine("-----");
    req = "PUT";
    if (Array.IndexOf((new string[] {"PUT", "POST"}), req) >= 0)  {
        Console.WriteLine("one.2.A"); // IS TRUE
    }
    req = "XPUT";
    if (Array.IndexOf((new string[] {"PUT", "POST"}), req) >= 0)  {
        Console.WriteLine("one.2.B"); // false
    }
    req = "PUTX";
    if (Array.IndexOf((new string[] {"PUT", "POST"}), req) >= 0)  {
        Console.WriteLine("one.2.C"); // false
    }
    req = "UT";
    if (Array.IndexOf((new string[] {"PUT", "POST"}), req) >= 0)  {
        Console.WriteLine("one.2.D"); // false
    }
    req = "PU";
    if (Array.IndexOf((new string[] {"PUT", "POST"}), req) >= 0)  {
        Console.WriteLine("one.2.E"); // false
    }
    req = "POST";
    if (Array.IndexOf((new string[] {"PUT", "POST"}), req) >= 0)  {
        Console.WriteLine("two.2.A");  // IS TRUE
    }
    req = "ASD";
    if (Array.IndexOf((new string[] {"PUT", "POST"}), req) >= 0)  {
        Console.WriteLine("three.2.A");  // false
    }

    Console.WriteLine("-----");
    req = "PUT";
    if ((new string[] {"PUT", "POST"}.Contains(req)))  {
        Console.WriteLine("one.3.A"); // IS TRUE
    }
    req = "XPUT";
    if ((new string[] {"PUT", "POST"}.Contains(req)))  {
        Console.WriteLine("one.3.B");  // false
    }
    req = "PUTX";
    if ((new string[] {"PUT", "POST"}.Contains(req)))  {
        Console.WriteLine("one.3.C");  // false
    }
    req = "UT";
    if ((new string[] {"PUT", "POST"}.Contains(req)))  {
        Console.WriteLine("one.3.D");  // false
    }
    req = "PU";
    if ((new string[] {"PUT", "POST"}.Contains(req)))  {
        Console.WriteLine("one.3.E");  // false
    }
    req = "POST";
    if ((new string[] {"PUT", "POST"}.Contains(req)))  {
        Console.WriteLine("two.3.A");  // IS TRUE
    }
    req = "ASD";
    if ((new string[] {"PUT", "POST"}.Contains(req)))  {
        Console.WriteLine("three.3.A");  // false
    }

    Console.ReadKey();
    }
}

Le tue seconde due opzioni non fanno nemmeno la stessa cosa alla prima.
Kyle Delaney,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.