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