соответствует, если в списке строк указан c строка c#. - PullRequest
1 голос
/ 06 февраля 2020

Я должен добавить валидатор для столбца пароля, то есть он не должен допускать слово «Пароль» в Пароль на любом этапе .. означает, что «Password@1234» не должно быть разрешено. Итак, я использовал приведенный ниже код, который работает нормально:

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

Теперь я хочу сравнить несколько слов, значит, он не должен содержать «Пароль» или «Привет», скажем. Я пробовал ".Any", но он не работает.

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

Я следовал:

Проверьте, содержит ли строка в списке указанную c строку с Linq

для Any

Пожалуйста, помогите.

Ответы [ 3 ]

3 голосов
/ 06 февраля 2020

Да, вы можете попробовать Linq Any ( определение слова - это сложный вопрос , поэтому позвольте мне придерживаться вашей схемы: \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)
  } 

Давайте проведем несколько демонстраций:

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

Результат:

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
0 голосов
/ 06 февраля 2020

Вы можете попробовать следующее:

По регулярному выражению

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

или

По LINQ

var forbiddenWords = new List<string>() { "PASSWORD", "HELLO" };
bool res = forbiddenWords.Any(x => viewModel.Password.ToUpper().Contains(x));
0 голосов
/ 06 февраля 2020

Может быть, ваш. Любой не так. Вы пробовали это?

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

Работает просто отлично. Не нужно регулярное выражение.


Это неправильно:

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

это было бы что-то вроде (пример только для объяснения):

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

Итак, в этот код выше (который логически совпадает с Any ()), где вы вводите пароль? Вы зацикливаете список в поиске «Пароль» и не проверяете пароль по списку.

Если вы используете метод, который я показал выше, он должен работать так, как вам нравится. Я бы не стал это повторять, особенно если ваш список большой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...