Check if a string contains one of 10 characters

C#String

C# Problem Overview


I'm using C# and I want to check if a string contains one of ten characters, *, &, # etc etc.

What is the best way?

C# Solutions


Solution 1 - C#

The following would be the simplest method, in my view:

var match = str.IndexOfAny(new char[] { '*', '&', '#' }) != -1

Or in a possibly easier to read form:

var match = str.IndexOfAny("*&#".ToCharArray()) != -1

Depending on the context and performance required, you may or may not want to cache the char array.

Solution 2 - C#

As others have said, use IndexOfAny. However, I'd use it in this way:

private static readonly char[] Punctuation = "*&#...".ToCharArray();

public static bool ContainsPunctuation(string text)
{
    return text.IndexOfAny(Punctuation) >= 0;
}

That way you don't end up creating a new array on each call. The string is also easier to scan than a series of character literals, IMO.

Of course if you're only going to use this once, so the wasted creation isn't a problem, you could either use:

private const string Punctuation = "*&#...";

public static bool ContainsPunctuation(string text)
{
    return text.IndexOfAny(Punctuation.ToCharArray()) >= 0;
}

or

public static bool ContainsPunctuation(string text)
{
    return text.IndexOfAny("*&#...".ToCharArray()) >= 0;
}

It really depends on which you find more readable, whether you want to use the punctuation characters elsewhere, and how often the method is going to be called.


EDIT: Here's an alternative to Reed Copsey's method for finding out if a string contains exactly one of the characters.

private static readonly HashSet<char> Punctuation = new HashSet<char>("*&#...");

public static bool ContainsOnePunctuationMark(string text)
{
    bool seenOne = false;

    foreach (char c in text)
    {
        // TODO: Experiment to see whether HashSet is really faster than
        // Array.Contains. If all the punctuation is ASCII, there are other
        // alternatives...
        if (Punctuation.Contains(c))
        {
            if (seenOne)
            {
                return false; // This is the second punctuation character
            }
            seenOne = true;
        }
    }
    return seenOne;
}

Solution 3 - C#

String.IndexOfAny(Char[])

Here is the Microsoft's documentation.

Solution 4 - C#

If you just want to see if it contains any character, I'd recommend using string.IndexOfAny, as suggested elsewhere.

If you want to verify that a string contains exactly one of the ten characters, and only one, then it gets a bit more complicated. I believe the fastest way would be to check against an Intersection, then check for duplicates.

private static char[] characters = new char [] { '*','&',... };

public static bool ContainsOneCharacter(string text)
{
    var intersection = text.Intersect(characters).ToList();
    if( intersection.Count != 1)
        return false; // Make sure there is only one character in the text

    // Get a count of all of the one found character
    if (1 == text.Count(t => t == intersection[0]) )
        return true;

    return false;
}

Solution 5 - C#

var specialChars = new[] {'\\', '/', ':', '*', '<', '>', '|', '#', '{', '}', '%', '~', '&'};

foreach (var specialChar in specialChars.Where(str.Contains))
{
    Console.Write(string.Format("string must not contain {0}", specialChar));
}

Solution 6 - C#

Thanks to all of you! (And Mainly Jon!): This allowed me to write this:

    private static readonly char[] Punctuation = "$€£".ToCharArray();
   
    public static bool IsPrice(this string text)
    {
        return text.IndexOfAny(Punctuation) >= 0;
    }

as I was searching for a good way to detect if a certain string was actually a price or a sentence, like 'Too low to display'.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJade MView Question on Stackoverflow
Solution 1 - C#NoldorinView Answer on Stackoverflow
Solution 2 - C#Jon SkeetView Answer on Stackoverflow
Solution 3 - C#Jason WilliamsView Answer on Stackoverflow
Solution 4 - C#Reed CopseyView Answer on Stackoverflow
Solution 5 - C#nologoView Answer on Stackoverflow
Solution 6 - C#BernardGView Answer on Stackoverflow