Utilisation de C # pour vérifier si une chaîne contient une chaîne dans un tableau de chaînes


290

Je veux utiliser C # pour vérifier si une valeur de chaîne contient un mot dans un tableau de chaînes. Par exemple,

string stringToCheck = "text1text2text3";

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

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

}

Comment puis-je vérifier si la valeur de chaîne pour 'stringToCheck' contient un mot dans le tableau?


1
Ce blog compare de nombreuses techniques pour tester si une chaîne contient une chaîne: blogs.davelozinski.com/curiousconsultant/…
Robert Harvey

Réponses:


145

voici comment vous pouvez le faire:

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

MISE À JOUR: Peut-être que vous cherchez une meilleure solution .. reportez-vous à la réponse de @Anton Gogolev ci-dessous qui utilise LINQ.


3
Merci, j'ai modifié votre code en: if (stringToCheck.Contains (s)) et cela a fonctionné.
Theomax

5
Je l'ai fait si (stringArray.Contains (stringToCheck)) et cela fonctionne très bien, merci.
Tamara JQ

68
N'utilisez pas cette réponse, utilisez plutôt LINQ
AlexC

11
Petite remarque pour les personnes qui ne voient pas la méthode Contains sur le tableau de chaînes: vérifiez si vous avez un "using System.Linq;" espace de noms dans votre fichier de code :)
Sudhanshu Mishra

5
Linq n'est pas toujours disponible dans les logiciels hérités.
William Morrison

842

Voici comment:

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

Ceci vérifie si stringToCheckcontient une des sous-chaînes de stringArray. Si vous voulez vous assurer qu'il contient toutes les sous-chaînes, passez Anyà All:

if(stringArray.All(stringToCheck.Contains))

115
Note à soi: linq est incroyable, linq est incroyable, linq est incroyable! Je dois commencer à utiliser linq.
Fredrik Johansson

2
@Spooks Linq To Objects (qui est utilisé dans la vérification de chaîne de la réponse) peut être utilisé via LinqBridge sur .NET 2.0 albahari.com/nutshell/linqbridge.aspx
David Rettenbacher

1
comment feriez-vous cela avec l'invariance de cas?
Offler

14
@Offler Ce seraitstringArray.Any(s => s.IndexOf(stringToCheck, StringComparison.CurrentCultureIgnoreCase) > -1)
Anton Gogolev

2
comment obtenir quel élément du tableau correspond?
ibubi

44

Essaye ça:

Pas besoin d'utiliser LINQ

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

Agréable! Et quel avantage Linq pourrait-il avoir sur Array.IndexOf ??
Heckflosse_230

21
Cela ne résout pas du tout la question. IndexOf vous indique si un tableau contient une correspondance exacte pour une chaîne, la question d'origine est de savoir si une chaîne contient l'un d'un tableau de chaînes, que Linq gère facilement.
NetMage

Je sais que ce commentaire est en retard, mais pour ceux qui ne le savent pas, une chaîne est un tableau de caractères, donc les types de chaîne contiennent une méthode IndexOf ... donc @NetMage c'est une solution possible.
Blacky Wolf

3
@Blacky Wolf, avez-vous lu la question? Array.IndexOf vous indique si un tableau contient une valeur, l'OP voulait savoir si une valeur contient un membre d'un tableau, exactement l'opposé de cette réponse. Vous pouvez utiliser String.IndexOf avec Linq: stringArray.Any(w => stringToCheck.IndexOf(w) >= 0)mais la réponse Linq utilisant String.Contains a plus de sens, car c'est exactement ce qui est demandé.
NetMage

40

Utilisez simplement la méthode linq:

stringArray.Contains(stringToCheck)

4
Notez que Contains est une méthode d'extension et que vous devez le faireusing System.Linq;
isHuman

11
Cette réponse est à l'envers de la question.
NetMage

1
Comment cette réponse a-t-elle été votée autant de fois? 5 ans après la question et la solution est fondamentalement inversée par rapport à ce que la question demande.
Fus Ro Dah

1
peut-être juste inverser les noms des variables, ça ira?
Jean-François Fabre

8

Manière la plus facile et d'échantillon.

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

mieux est stringarray.Exists (entity => entity == stringtocheck)
Marcel Grüger

Je pense que vous ne peux pas appel EXISTE méthode méthode directement à partir array.Exists de chaîne peut utiliser directement pour la liste <T> .Donc devrait utiliser la méthode statique array.exist <T> pour la chaîne array.check ici => msdn.microsoft.com/en- fr / library / yw84x8be (v = vs.110) .aspx
Jze

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

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

2
Je ne pense pas que c'est ce que demande la question.
Pang

5

Quelque chose comme ça peut-être:

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

Il s'agit d'une meilleure solution, car il s'agit d'une vérification de sous-chaîne par rapport aux mots d'une liste au lieu d'une vérification de correspondance exacte.
Roy B

Belle réponse, mais wow c'est difficile à lire par rapport au C # moderne même sans Linq; aussi, String.Containspeut-être mieux que String.IndexOfsi vous ne voulez pas ignorer la casse, car Microsoft a oublié deux arguments, String.Containsvous devez écrire le vôtre. Considérez:Array.Exists(stringArray, s => stringToCheck.IndexOf(s, StringComparison.OrdinalIgnoreCase) > -1)
NetMage

3

L'utilisation de Linq et du groupe de méthodes serait le moyen le plus rapide et le plus compact de le faire.

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

3

Vous pouvez définir vos propres méthodes string.ContainsAny()et string.ContainsAll(). En prime, j'ai même introduit une string.Contains()méthode qui permet une comparaison insensible à la casse, etc.

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

Vous pouvez les tester avec le code suivant:

    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

J'utilise ce qui suit dans une application console pour vérifier les arguments

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

2

J'utiliserais Linq mais cela peut toujours être fait par:

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

1

Essayer:

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

Vous pouvez également faire la même chose que Anton Gogolev suggère de vérifier si un article dans stringArray1correspond tout élément dans stringArray2:

if(stringArray1.Any(stringArray2.Contains))

De même, tous les éléments de stringArray1 correspondent à tous les éléments de stringArray2:

if(stringArray1.All(stringArray2.Contains))


0

essayez ceci, voici l'exemple: Pour vérifier si le champ contient l'un des mots du tableau. Pour vérifier si le champ (someField) contient l'un des mots du tableau.

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

J'ai utilisé une méthode similaire à l'IndexOf de Maitrey684 et à la boucle foreach de Theomax pour créer cela. (Remarque: les 3 premières lignes de "chaîne" ne sont qu'un exemple de la façon dont vous pouvez créer un tableau et le mettre au format approprié).

Si vous souhaitez comparer 2 tableaux, ils seront délimités par des points-virgules, mais la dernière valeur n'en aura pas après. Si vous ajoutez un point-virgule à la forme chaîne du tableau (c.-à-d. A; b; c devient a; b; c;), vous pouvez faire correspondre en utilisant "x;" quelle que soit sa position:

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 prend la valeur true si la chaîne recherchée correspond à n'importe quel élément des «lignes» du tableau.


0

Essaye ça

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

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

Il vous renverra la ligne avec la première incidence du texte que vous recherchez.


0

S'il stringArraycontient un grand nombre de chaînes de longueur variable, envisagez d'utiliser un Trie pour stocker et rechercher le tableau de chaînes.

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

Voici l'implémentation de la 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;
}

Si toutes les chaînes stringArrayont la même longueur, vous feriez mieux d'utiliser simplement un HashSetau lieu d'unTrie

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

Solution simple, pas besoin de linq any

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


2
Que faire si l'une des valeurs du tableau contient votre délimiteur?
Tyler Benzing

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

0

Essayez ceci, pas besoin de boucle ..

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

}

0

Pour compléter les réponses ci-dessus, pour la vérification IgnoreCase , utilisez:

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

Existe-t-il un moyen d'obtenir également l'index de la correspondance avec cela? Merci.
Si8

0

Pour mon cas, les réponses ci-dessus n'ont pas fonctionné. Je cherchais une chaîne dans un tableau et je l'assignais à une valeur booléenne. J'ai modifié la réponse de @Anton Gogolev et supprimé la Any()méthode et mis l' stringToCheckintérieur de la Contains()méthode.

bool = stringArray.Contains(stringToCheck);

0

Utilisation des méthodes Find ou FindIndex de la classe Array :

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

-1

J'ai utilisé le code suivant pour vérifier si la chaîne contenait l'un des éléments du tableau de chaînes:

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

3
Cela définit Text = "matched"autant de fois qu'il stringToCheckcontient de sous-chaînes de stringArray. Vous pouvez mettre un breakou returnaprès le devoir.
Dour High Arch

-1

Trois options ont été démontrées. Je préfère trouver le troisième comme le plus concis.

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

Vos deux dernières options ne font même pas la même chose lors de la première.
Kyle Delaney
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.