Разбить строку на отдельные функциональные части

Задача: разделить строку на части по разделителю ";" Функция имеет вид Sum(expr) или Sum(expr;condition). Вложенность теоретически бесконечна

Входные данные: Sum(a;b) Выходные данные expr = a condition = b

Входные данные: Sum(a) Выходные данные expr = a condition = null

Входные данные: Sum(Sum(a;c);b) Выходные данные expr = Sum(a;c) condition = b

Входные данные: Sum(Sum(a);Sum(b;d)) Выходные данные expr = Sum(a) condition = Sum(b;d)

Подскажите, как лучше обрабатывать такие ситуации. Пробовал через поиск IndexOf(";"), некорректно работает в случае вложенности


Ответы (2 шт):

Автор решения: Qbic

Пришел к такому решению. Комментарии приветствуются) На вход в функцию передается только внутренняя часть формулы

private static List<string> SplitByDelimeter(string expression)
    {
        var res = new List<string>();
        Stack<char> brackets = new Stack<char>();
        StringBuilder builder = new StringBuilder();
        foreach (var ch in expression)
        {
            if (ch == '(')
                brackets.Push(ch);
            if (ch == ')')
                brackets.Pop();

            if (ch == ';' && brackets.Count == 0)
            {
                res.Add(builder.ToString());
                builder = new StringBuilder();
                continue;
            }

            builder.Append(ch);
        }

        if (builder.Length > 0)
            res.Add(builder.ToString());

        return res;
    }
→ Ссылка
Автор решения: Wiktor Stribiżew

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

var pattern = @"(?x)Sum\(      # текст Sum(
  (                            # Начало первой подмаски
   \w*(?:\((?>[^()]+|(?<c>)\(|(?<-c>)\))*(?(c)(?!))\))? # 1 слово и необязательная подстрока между ( и )
  )                            # Конец первой подмаски
  (?:                          # Начало незахватывающей подмаски
    ;                          # точка с запятой
    (\w*(?:\((?>[^()]+|(?<c>)\(|(?<-c>)\))*(?(c)(?!))\))?) # см. выше
  )?                           # Конец незахватывающей подмаски, 1 и 0 раз
\)                             # Символ ) ";

См. пример использования регулярного выражения

Результаты:

введите сюда описание изображения

→ Ссылка