Есть ли в C# функция для проверки последовательности списка с помощью регулярных выражений - PullRequest
2 голосов
/ 24 апреля 2020

У меня есть два списка , и мне нужно проверить, совпадают ли последовательности элементов в обоих списках с Regex.

For instance I have one list with items {c1, s1?, s2?, s3}.

Valid Sequence:   {c1, s1, s2, s3}, 
                  {c1, s3}.

Invalid Sequence: {c1, c1, s1, s2, s3}, 
                  {c1, s2, s1, s3}, 
                  {c1},
                  {s3, c1}.

1 Ответ

3 голосов
/ 24 апреля 2020

Предполагая, что какое-то delimiter, скажем "," никогда не появляется внутри элементов, которые мы можем построить регулярное выражение :

  using System.Linq;
  using System.Text.RegularExpressions;

  ...

  const string delimiter = ",";

  private static string ItemToRegex(string item, int index) {
    string value = item.TrimEnd('+', '*', '?');
    string suffix = item.Substring(value.Length);

    return $"(?:{(index <= 0 ? "" : delimiter)}{Regex.Escape(value)}){suffix}";
  }

  private static Regex ListToRegex(IEnumerable<string> list) {
    string pattern = "^" + string.Concat(list.Select((item, index) => ItemToRegex(item, index))) + "$";

    return new Regex(pattern);
 }

Затем для проверки последовательность, которую мы должны Join ее элементы "delimiter" и использовать регулярное выражение:

 List<string> list = new List<string>() {
    "c1", "s1?", "s2?", "s3"
 };

 Regex regex = ListToRegex(list);

 List<string> testList = new List<string>() {"c1", "s3"};

 Console.Write(regex.IsMatch(testList.Join(delimiter)));

Демо:

  List<string> list = new List<string>() {
    "c1", "s1?", "s2?", "s3"
  };

  Regex regex = ListToRegex(list);

  List<string>[] tests = new List<string>[] {
    new List<string>() {"c1", "s1", "s2", "s3"},
    new List<string>() {"c1", "s3"},
    new List<string>() {"c1", "c1", "s1", "s2", "s3"},
    new List<string>() {"c1", "s2", "s1", "s3"},
    new List<string>() {"c1" },
    new List<string>() {"s3", "c1" },
  };

  string report = string.Join(Environment.NewLine, tests
    .Select(test => new {
      valid = regex.IsMatch(string.Join(delimiter, test)) ? "Valid" : "Invalid",
      text = string.Join(", ", test)
    })
    .Select(test => $"{test.valid,-8} :: {test.text}"));

  Console.Write(report);

Результат:

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