Как найти запятую, которая не находится в скобках в регулярном выражении .net? - PullRequest
1 голос
/ 27 февраля 2009

Используя некоторые расширения, предоставляемые .net, можно найти группы скобок, используя что-то вроде этого:

^(\w+)\(((?>[^()]+|\((?<D>)|\)(?<-D>))*(?(D)(?!)))\)(.*)$

Это будет соответствовать следующему:

Func(innerfunction(arg)).DoSomething()

Со следующими группами:

  • Группа 1: Func
  • Группа 2: внутренняя функция (arg)
  • Группа 3: .DoSomething ()

Мой вопрос: как мне сопоставить запятые, учитывая, находятся ли они в скобках или нет? Например, регулярное выражение для оценки:

Func(innerFunction(arg1, arg2), arg3).DoSomething()

Должен дать:

  • Группа 1: Func
  • Группа 2: внутренняя функция (arg1, arg2)
  • Группа 3: arg3
  • Группа 4: .DoSomething ()

Спасибо.

Ответы [ 3 ]

0 голосов
/ 27 февраля 2009

Хотя это не невозможно, я не советую использовать для этого регулярные выражения.

Проблема в том, что выражения, как правило, либо полностью жадные, либо совершенно не жадные. Например, возьмите следующий ввод:

(а,) б, (с, (д,) е)

Жадное выражение будет максимально соответствовать. Он будет видеть все как в скобках, и поэтому вернет ничто .

Несжатое выражение будет правильно соответствовать запятой b, но оно также будет соответствовать запятой e, поскольку оно будет видеть (c,(d,) как одну полную группу.

Теперь, похоже, вы уже понимаете эти проблемы, и что механизм регулярных выражений .Net имеет функцию, которая позволит вам в некоторой степени преодолеть это. Но выражение результата будет уродливым, не поддерживаемым, не очень переносимым, и его легко ошибиться. Если вы действительно не знаете, что делаете, вероятно, лучше всего искать другое решение.

0 голосов
/ 27 февраля 2009

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

Поэтому я рекомендую вам создать парсер, который разбивает уровни вложенности. Читайте ввод за символом. Когда «(» увеличивает уровень, когда «)» уменьшает уровень, когда «,» разделяется.

0 голосов
/ 27 февраля 2009

Я думаю, что нашел это. У кого-нибудь есть встречный пример:

^([^()]*?|.*\((?>[^()]+|\((?<D>)|\)(?<-D>))*(?(D)(?!))\).*?),(.*)$

Это будет соответствовать этому выражению:

func1(arg2, func3(arg3, arg4)), func2(arg5, arg6).property

как:

  • Группа1: func1 (arg2, func3 (arg3, arg4))
  • Группа2: func2 (arg5, arg6) .property

Это решение ищет только одну запятую, но имеет дело с произвольной глубиной круглых скобок.

ОБНОВЛЕНИЕ: Gumbo предоставил контрпример:

func1((arg1), arg2), func2(arg3).property

Получить разделить на:

  • Группа1: func1 ((arg1)
  • Группа 2: arg2), func2 (arg3) .property

ОДНАКО : Превратив первое «любое совпадение» в нежадное, можно решить:

^([^()]*?|.*?\((?>[^()]+|\((?<D>)|\)(?<-D>))*(?(D)(?!))\).*?)\s*,\s*(.+)$

Любой другой контрпример?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...