Прошу помочь составить Regexp c#
У меня есть Regexp, который находит строку в скобках "верхнего уровня":
(\()((?>[^()]+|\((?<depth>)|\)(?<-depth>))*(?(depth)(?!)))(\))
Пример:
3.786 + 2x * ((1 + 1 - (2 + 4)) + 12*31) = pow(3, -2(5-4)) + 3/4
Я хочу что бы искались только те строки, в которых нет знака ,. Можно как то его исключить из результата?
То есть, я хочу что бы в данном примере нашёлся только 1 матч, тот что выделен зелёным:
Ответы (2 шт):
Если уж отвечать на поставленный вопрос, то вот:
\([^,]*\([^,]*\)[^,]*\)
Дополнение
Проблемы предложенного выше варианта очевидны. Возьмём за основу такой шаблон:
(\(([^,()]*\([^,()]+\)[^,()]*)+\))
Это РВ ведет себя более предсказуемо в том смысле, что находит скобочные выражения строго одного уровня вложенности.
Т.е. никаких лишних скобок "внутри":

Этот шаблон легко расширить до следующего уровня (и в принципе любого), просто дублируя начальную и конечную конструкцию:
(\(([^,()]*\(([^,()]*\([^,()]+\)[^,()]*)+\)[^,()]*)+\))
<-- ^^^^^^^^^^ ^^^^^^^^^^^ -->
Теперь, объединим эти шаблоны через ИЛИ:
(\(([^,()]*\(([^,()]*\([^,()]+\)[^,()]*)+\)[^,()]*)+\))|(\(([^,()]*\([^,()]+\)[^,()]*)+\))
Это не решает проблему в целом, но для ряда задач с известными ограничениями может подойти.
Не ответ конечно, но раз уж код написал, не пропадать же добру. Делает примерно то же,что регулярка
IEnumerable<string> GetMatches(string input)
{
int ind = 0;
while(ind < input.Length)
{
while(ind < input.Length && input[ind] != '(') ind++;
var start = ind;
var deep = 1;
ind++;
while(ind < input.Length && deep > 0)
{
if (input[ind] == '(') deep++;
if (input[ind] == ')') deep--;
ind++;
}
if (deep == 0)
{
var ret = input.Substring(start, ind - start);
if (!ret.Contains(',')) yield return ret;
}
}
}
проверка
var exp = "3.786 + 2x * ((1 + 1 - (2 + 4)) + 12*31)) = pow(3, -2(5-4)) + 3/4";
foreach (var m in GetMatches(exp))
Console.WriteLine(m);
Вывод
((1 + 1 - (2 + 4)) + 12*31)



