Захватывать подстроку внутри разделителей и исключать символы с помощью регулярных выражений - PullRequest
0 голосов
/ 01 ноября 2018

Как может выглядеть шаблон регулярного выражения для захвата подстроки между 2 разделителями, но исключая некоторые символы (если есть) после первого разделителя и до последнего разделителя (если есть)? Например, строка ввода выглядит следующим образом:

var input = @"Not relevant {

#AddInfoStart Comment:String:=""This is a comment"";

AdditionalInfo:String:=""This is some additional info"" ;

# } also not relevant";

Захват должен содержать подстроку между "{" и "}", но исключая любые пробелы, символы новой строки и строку "#AddInfoStart" после начального разделителя "{" (только если они есть), а также исключая любые пробелы , новые строки и ";" и символы "#" перед конечным разделителем "}" (также, если они есть).

Захваченная строка должна выглядеть следующим образом

Comment:String:=""This is a comment"";

AdditionalInfo:String:=""This is some additional info""

Возможно, что есть пробелы до или после внутренних разделителей ":" и ": =", а также что значение после ": =" не всегда помечается как строка, например что-то вроде:

{  Val1 : Real := 1.7  }

Для массивов используется следующий синтаксис:

arr1 : ARRAY [1..5] OF INT := [2,5,44,555,11];
arr2 : ARRAY [1..3] OF REAL

1 Ответ

0 голосов
/ 01 ноября 2018

Это мое решение:

  1. Удалить содержание за скобками
  2. Используйте регулярное выражение, чтобы получить значения в скобках

Код:

var input = @"Not relevant {

#AddInfoStart Comment:String:=""This is a comment"";

            Val1 : Real := 1.7

AdditionalInfo:String:=""This is some additional info"" ;

# } also not relevant";

// remove content outside brackets
input = Regex.Replace(input, @".*\{", string.Empty);
input = Regex.Replace(input, @"\}.*", string.Empty);

string property = @"(\w+)"; 
string separator = @"\s*:\s*"; // ":" with or without whitespace
string type = @"(\w+)"; 
string equals = @"\s*:=\s*"; // ":=" with or without whitespace
string text = @"""?(.*?)"""; // value between ""
string number = @"(\d+(\.\d+)?)"; // number like 123 or with a . separator such as 1.45
string value = $"({text}|{number})"; // value can be a string or number
string pattern = $"{property}{separator}{type}{equals}{value}";

var result = Regex.Matches(input, pattern)
                  .Cast<Match>()
                  .Select(match => new
                  {
                      FullMatch = match.Groups[0].Value, // full match is always the 1st group
                      Property = match.Groups[1].Value, 
                      Type = match.Groups[2].Value, 
                      Value = match.Groups[3].Value 
                  })
                  .ToList();
...