Как найти строку с начальным шаблоном и содержит шаблон - PullRequest
0 голосов
/ 10 января 2019

Я изучал этот пост , пытаясь собрать регулярное выражение ac #, которое выполняет следующее: Найти, содержит ли строка другую строку, начинающуюся с определенных букв и содержащую определенные символы.

Вот 1 конкретный пример строки сена:

NOT SUPPCODE{900mm,1500mm} and IDU{true}

Мне нужно выяснить, содержит ли строка стога сена NOT (предпочтительно без учета регистра), за которым следует 1 пробел, за которым сразу следует неразрывное слово "пробел", которое содержит следующие 3 символа (по порядку, но не рядом): {,}. Другими словами, должны быть 1 или более запятых, заключенных в левые / правые фигурные скобки. Пробелы внутри фигурных скобок хороши , но между SUPPCODE (в данном примере) и левой фигурной скобкой не должно быть пробелов.

Мой пример стога сена на самом деле соответствует этому шаблону, потому что есть NOT (не обязательно должен быть в начале строки), за которым следует один пробел, за которым следует последовательность символов, которая содержит левый вьющийся скобка, запятая и правильная фигурная скобка. Эти 3 символа не будут соседними.

Вот код C #, который я собрал на основе упомянутого выше поста, который не работает для меня:

public static bool ContainsRegex(string haystack, string startsWith, string contains) {
   var regex = new Regex("(?=.*" + contains + ")^" + startsWith);
   int matches = regex.Matches(haystack).Count;
   return matches > 0;
}

называется так:

bool isFound = ContainsRegex("NOT SUPPCODE{900mm,1500mm} and IDU{true}", "NOT ", "{,}");

Эти строковые параметры, конечно, будут динамическими и всегда будут разными во время выполнения.

Моя функция всегда возвращает false даже в тех случаях (как показано выше), когда она должна возвращать true.

Вот несколько строк с отрицательным тестом, которые должны возвращать false:

SUPPCODE{900mm,1500mm} and IDU{true} // doesn't begin with NOT
STUFF SUPPCODE{900mm,1500mm} and IDU{true} // doesn't begin with NOT
NOT SUPPCODE{900mm} and IDU{true} // no comma between curly braces
NOT SUPPCODE,5,6900mm} and IDU{true} // no left curly brace
NOTSUPPCODE{900mm,1500mm} and IDU{true} // no space between NOT and SUPPCODE
NOT SUPPCODE {900mm,1500mm} and IDU{true} // space between SUPPCODE and left curly brace

Что я делаю не так?

1 Ответ

0 голосов
/ 10 января 2019

Вы можете использовать

public static bool ContainsRegex(string haystack, string startsWith, string contains) 
{
    var delims = contains.Select(x => x.ToString().Replace("\\", @"\\").Replace("-", @"\-").Replace("^", @"\^").Replace("]", @"\]")).ToList();
    var pat = $@"^{startsWith} \w+{Regex.Escape(contains.Substring(0,1))}[^{string.Concat(delims)}]*{Regex.Escape(contains.Substring(1,1))}[^{delims[0]}{delims[2]}]*{Regex.Escape(contains.Substring(2,1))}";
    // Console.WriteLine(pat); // => ^NOT \w+\{[^{,}]*,[^{}]*}
    return Regex.IsMatch(haystack, pat, RegexOptions.IgnoreCase);
}

Вот пример :

var strs = new[] { "SUPPCODE{900mm,1500mm} and IDU{true}",
            "STUFF SUPPCODE{900mm,1500mm} and IDU{true}",
            "NOT SUPPCODE{900mm} and IDU{true}",
            "NOT SUPPCODE,5,6900mm} and IDU{true}",
            "NOTSUPPCODE{900mm,1500mm} and IDU{true}",
            "NOT SUPPCODE {900mm,1500mm} and IDU{true}",
            "NOT SUPPCODE{900mm,1500mm} and IDU{true}"};
foreach (var s in strs)
    Console.WriteLine($"{s} => {ContainsRegex(s, "NOT", "{,}")}");

Выход:

SUPPCODE{900mm,1500mm} and IDU{true} => False
STUFF SUPPCODE{900mm,1500mm} and IDU{true} => False
NOT SUPPCODE{900mm} and IDU{true} => False
NOT SUPPCODE,5,6900mm} and IDU{true} => False
NOTSUPPCODE{900mm,1500mm} and IDU{true} => False
NOT SUPPCODE {900mm,1500mm} and IDU{true} => False
NOT SUPPCODE{900mm,1500mm} and IDU{true} => True

Предполагается, что аргумент contains имеет только 3 символа: начальный разделитель - первый, средний - обязательный символ внутри, а затем третий символ - конечный символ.

См. Также полученный пример регулярного выражения .

Детали

  • ^ - начало строки
  • NOT - startsWith строка
  • - пробел
  • \w+ - 1+ слово символов
  • \{ - начальный разделитель
  • [^{,}]* - 0+ символов, кроме символов-разделителей
  • , - средний обязательный символ
  • [^{}]* - 0+ символов кроме начальных и конечных символов-разделителей
  • } - конечный разделитель.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...