简体   繁体   中英

How to check if a string contains chars that are outside of a given char list

I have a string, and I need to check if this string contains any chars that are not in a given list.

Suppose i have this allowed chars new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' , '.'}

If string is "54323.5" - this will be ok !

If string is "543g23.5" - this won't be ok since it contains "g" which is not in the list of my allowed chars.

An empty string is considered invalid.

I am trying to achieve this by using "IndexOfAny()" but with no luck so far. Of course passing all the unallowed chars to this method won't be a solution.

Please note that the list of the allowed chars may change and changing the validation algorithm based on the list change is not considered a solution.

For you guys that asked me the code that I tried, here it is:

        private bool CheckInvalidInput(string stringToCheck)
    {
        char[] allowedChars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

        var chars = Enumerable.Range(0, char.MaxValue + 1)
                  .Select(i => (char)i)
                  .ToArray();

        var unallowedChars = chars.Except(allowedChars).ToArray();

        bool validString = true;
        if(stringToCheck.IndexOfAny(unallowedChars) != -1)
        {
            validString = false;
        }

        return validString;
    }

Hope that you will come with a better solution :D.

This can be done using a very simple pattern. Regex.IsMatch(yourString, @"^[\\d.]+$");

^ is the beginning of the line

[\\d.]+ matches one or more characters (either . or 0-9 )

$ is the end of the line

Demo

Edit: This will also match .

If this behavior is not intended, then try using this ^(?=\\d)[\\d.]+$

This is straightforward to achieve. The string type implements IEnumerable<char> , so you can use the LINQ All method to check that all its characters satisfy a predicate. In your case, the predicate is that each character is contained in the allowedChars set, so you can use the Contains method:

private static bool CheckInvalidInput(string stringToCheck, IEnumerable<char> allowedChars)
{
    return stringToCheck.All(allowedChars.Contains);
}

If your allowedChars set gets large, you would want to convert it to a HashSet<char> for better performance.

Full example:

using System;
using System.Linq;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        // var allowedChars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.' };
        var allowedChars = "0123456789.";

        Console.WriteLine(CheckInvalidInput("54323.5", allowedChars));   // True
        Console.WriteLine(CheckInvalidInput("543g23.5", allowedChars));  // False
    }

    private static bool CheckInvalidInput(string stringToCheck, IEnumerable<char> allowedChars)
    {
        return stringToCheck.All(allowedChars.Contains);
    }
}

If an array of allowed chars is dynamic, you can create procedure which would accept an array of allowed chars and construct pattern on the fly. Please, note that you have to escape certain chars in order to use in Regex:

static void TestRegex(char[] check_chars)
{
    string[] inputs = { "54323.5", "543g23.5" };
    var check_chars2 = check_chars.Select(c => Regex.Escape(c.ToString()));
    string pattern = "^(" + string.Join("|", check_chars2) + ")+$";
    foreach (string input in inputs)
    {
        WriteLine($"Input {input} does{(Regex.IsMatch(input, pattern) ? "" : " not")} match");
    }
}

// Output:
// Input 54323.5 does match
// Input 543g23.5 does not match

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM