Ram Singh
Ram Singh

Reputation: 6918

match if string list has specific string c# tried .Any

i have to add validator for password column, i.e. it should not allow "Password" word in Password at any stage.. means "Password@1234" should not be allowed. So i was using below code which is working fine:

Regex.IsMatch(viewModel.Password.ToUpper(), @"(\w*PASSWORD\w*)", RegexOptions.IgnoreCase)

Now i want to compare multiple words means it should not contains "Password" or "Hello" lets say. I have tried ".Any" but it is not working.

if (myList.Any(str => str.Contains("Password")))

I have followed:

Check if a string within a list contains a specific string with Linq

for Any

Please help.

Upvotes: 1

Views: 104

Answers (3)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

Yes, you can try Linq Any (word definition is a complex question, that's why let me stick to your pattern: \w*{word_to_find}\w*):

  List<string> ForbiddenWords = new List<string>() {
    "this",
    "password",
    "bla-bla-bla",
    "123",
  };

  Regex[] invalidPasswords = ForbiddenWords
    .Select(word => new Regex($@"\w*{Regex.Escape(word)}\w*", RegexOptions.IgnoreCase))
    .ToArray();

  ...

  if (invalidPasswords.Any(regex => regex.IsMatch(viewModel.Password))) {
    // Password is invalid it contains forbidden word(s)
  } 

Let's have some demonstration:

  string[] tests = new string[] {
    "MyPassWord",
    "PassWord",
    "PassWord@123",
    "PassWord@5678",
    "It's_PassWord@5678",
    "ABC123",
    "123",
    "1234",
    "pass",
    "word",
    "swar",
  };

  Func<string, bool> Validator = (password) => 
    !invalidPaswords.Any(regex => regex.IsMatch(password));

  string report = string.Join(Environment.NewLine, tests
    .Select(test => $"{test,-20} : {(Validator(test) ? "OK" : "Invalid")}"));

  Console.Write(report);

Outcome:

MyPassWord           : Invalid
PassWord             : Invalid
PassWord@123         : Invalid
PassWord@5678        : Invalid
It's_PassWord@5678   : Invalid
ABC123               : Invalid
123                  : Invalid
1234                 : Invalid
pass                 : OK
word                 : OK
swar                 : OK

Upvotes: 3

Furkan &#214;zt&#252;rk
Furkan &#214;zt&#252;rk

Reputation: 1416

You can try the followings,

By regex

bool res = Regex.IsMatch(viewModel.Password.ToUpper(), @"(\w*PASSWORD\w*)|(\w*HELLO\w*)", RegexOptions.IgnoreCase);

or

By LINQ

var forbiddenWords = new List<string>() { "PASSWORD", "HELLO" };
bool res = forbiddenWords.Any(x => viewModel.Password.ToUpper().Contains(x));

Upvotes: -1

Lucca Ferri
Lucca Ferri

Reputation: 1347

Maybe your .Any is wrong. Have you tried this?

    static bool ContainsBlacklistedWords(string password, string[] blacklist)
    {
        return blacklist.Any(s => password.Contains(s, StringComparison.CurrentCultureIgnoreCase));
    }
    static void Main(string[] args)
    {
        string password = "foobar";
        string[] blacklist = new[] { "hello", "password" };

        if (ContainsBlacklistedWords(password, blacklist))
        {
            Console.WriteLine("Contains blocked words.");
        }
        else
        {
            Console.WriteLine("OK");
        }
     }

Works just fine. No Regex needed.


This is wrong:

if (myList.Any(str => str.Contains("Password")))

this would be something like (example for explaination only):

foreach (var str in myList)
{
      if (str.Contains("Password"))
      {
              return true;
      }
}
return false;

So, in this code above (which is logically the same as the Any()), where are you feeding the password? You are looping the list searching for "Password", and not checking a password against a list.

If you use the method that I showed above, it should work the way you like it. I wouldn't regex that, especially if your list is big.

Upvotes: 0

Related Questions