How to check if a String contains any of some strings

201,766

Solution 1

If you are looking for single characters, you can use String.IndexOfAny().

If you want arbitrary strings, then I'm not aware of a .NET method to achieve that "directly", although a regular expression would work.

Solution 2

Well, there's always this:

public static bool ContainsAny(this string haystack, params string[] needles)
{
    foreach (string needle in needles)
    {
        if (haystack.Contains(needle))
            return true;
    }

    return false;
}

Usage:

bool anyLuck = s.ContainsAny("a", "b", "c");

Nothing's going to match the performance of your chain of || comparisons, however.

Solution 3

Here's a LINQ solution which is virtually the same but more scalable:

new[] { "a", "b", "c" }.Any(c => s.Contains(c))

Solution 4

var values = new [] {"abc", "def", "ghj"};
var str = "abcedasdkljre";
values.Any(str.Contains);

Solution 5

You can try with regular expression

string s;
Regex r = new Regex ("a|b|c");
bool containsAny = r.IsMatch (s);
Share:
201,766
Stavros
Author by

Stavros

.Net software developer

Updated on January 27, 2022

Comments

  • Stavros
    Stavros over 2 years

    I want to check if a String s, contains "a" or "b" or "c", in C#. I am looking for a nicer solution than using

    if (s.contains("a")||s.contains("b")||s.contains("c"))
    
  • Joel Coehoorn
    Joel Coehoorn over 13 years
    +1, though since he's looking for single characters a linq solution or indexOfAny might be more efficient.
  • Stavros
    Stavros over 13 years
    +1 for the regular expression. that's what I would have gone for, if there wasn't IndexOfAny
  • Guffa
    Guffa over 13 years
    That is scalable in the sense that it's easy to add characters, not in the sense of performance... :)
  • Steven Sudit
    Steven Sudit over 13 years
    Regular expressions are overkill for this.
  • Jeff Mercado
    Jeff Mercado over 13 years
    Ah yes, of course. Perhaps "more extensible" would have been a better choice of words.
  • Steven Sudit
    Steven Sudit over 13 years
    The performance won't be terrible. Better than an interpreted regexp, anyhow.
  • Steven Sudit
    Steven Sudit over 13 years
    You certainly can, but I don't see why you would want to when almost anything else is better.
  • bruceboughton
    bruceboughton over 13 years
    What makes people say regexes are overkill for this? If the regex is compiled once and used multiple times, and you have strings with only c in them or c near the beginning and a, b near the end, the regex would be far more efficient.
  • bruceboughton
    bruceboughton over 13 years
    Agreed. This solves the problem of multiple scans when the first conditions don't match. Wonder what the overhead of the lambda is though? Shouldn't be much once though.
  • Trevor
    Trevor over 7 years
    Awesome answer just for completeness you can split your incoming string up into an array first e.g: var splitStringArray = someString.Split(' '); Then you can do something like: if(someStringArray.Any(s => otherString.Contains(s))) { // do something } Hope that helps someone for clarity.
  • Roma Borodov
    Roma Borodov over 7 years
    Just one note to improve this answer. You could write it even more ellegant with params keyword : ContainsAny(this string input, StringComparison comparisonType, params string [] containsKeywords) and use like input.ContainsAny(substrings, StringComparison.CurrentCultureIgnoreCase, "string", "many substrings"...etc)
  • simonkaspers1
    simonkaspers1 about 7 years
    Adding new short syntax to this nice solution public static bool ContainsAny(this string haystack, params string[] needles) { return needles.Any(haystack.Contains); }
  • Nate Wilkins
    Nate Wilkins over 6 years
    The methods HasWantedCharacters accept two or three strings. The first string we want to check for certain characters. The second string, all the characters that we'll look for in the first. The overloaded method provides output to the caller (ie Main) as a third string. A nested foreach statement goes through each character in the source and compares it, one-by-one; with those characters we're checking for. If one of the characters is found, it returns true. The overloaded method outputs a string of characters found matching those checked for, but won't return until all are out. Helpful?
  • Nate Wilkins
    Nate Wilkins over 6 years
    Feel free to start a C# console project and copy the code inside the program class-be sure to replace the main method. Tinker with the two strings (goodUserName and badUserName) and you might see just what the methods do and how they work. The examples are longer so as to provide a workable solution that can be modified without delimiters like commas. Escape sequences are just one way to represent the single quote and backslash if you need to check for them.
  • MAFAIZ
    MAFAIZ about 6 years
    Its not worked for special characters like - , ' " . ` =
  • RollerKostr
    RollerKostr about 6 years
    Simple and obvious solution. But is there any good ready to use implementation that not require multiple iterations through haystack string? I can implement it by myself, iterating through haystack string characters and comparing first characters of needles sequentially in one go, but I can't believe that such trivial solution not implemented yet in some well-known NuGet library.
  • jmdon
    jmdon about 6 years
    @RollerKostr It's not built into C# (yet) so why add additional dependencies in your project for such a simple solution?
  • RK Coder
    RK Coder over 3 years
    This is elegant! Thanks!
  • Gonzo345
    Gonzo345 over 2 years
    This is the way. Bear in mind about cases! You people might want to apply ToUpperInvariant() on both "sides"
  • WtFudgE
    WtFudgE about 2 years
    cool i didn't know that was possible
  • Unknown Artist
    Unknown Artist almost 2 years
    it's cool trick. tnx.