5

Я имею следующую структуру:

(Q){(W){g}(E){z}}

Мне необходимо достать то, что находится в круглых и фигурных скобках первого уровня. Т.е.

Q и (W){g}(E){z}

Пробовал "\((.+?)\){.*?}" но это обрезает последнюю фигурную скобку.

VenZell
  • 19,872
Kojan
  • 85
  • 2
    Какой диалект регулярных выражений используется ? Возможны ли внутри первых круглых скобок еще круглые скобки ? – Mike May 31 '17 at 08:44
  • @Mike Круглые скобки содержат имя параметра, фигурные содержат параметры. Параметр может содержать другие параметры. – Kojan May 31 '17 at 13:54
  • Это PHP, C#, Java(Script)?? – Wiktor Stribiżew May 31 '17 at 14:30
  • @WiktorStribiżew для меня это не имело особого значения. Мне необходимо было понять свою ошибку. C# – Kojan May 31 '17 at 14:40
  • В C# все данные ниже ответы не работают, так как в нем нет поддержки рекурсии в регулярных выражениях. – Wiktor Stribiżew May 31 '17 at 14:41

3 Answers3

3

Используйте рекурсивный шаблон, например в таком варианте

/\(((?>[^()]+|(?R))*)\)|{((?>[^{}]+|(?R))*)}/g

Результат будет в первой или второй группе в зависимости от вида скобок.

Пример тут https://regex101.com/r/HRABRe/1

Visman
  • 16,518
  • 8
  • 26
  • 56
3

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

(                 # начинаем первую группу захвата
 \(               # первый символ - круглая скобка
   (              # вторая группа захвата - требуемый результат
    (?:
     (?1) |       # внутри которой может быть повторено выражение всей первой группы
    .)*?          # или любой символ, много раз
   )
 \)
)

Все выражение целиком выглядит так:

(\(((?:(?1)|.)*?)\))({((?:(?3)|.)*?)})

Требуемые результаты в 2 и 4 группах захвата. Если внутри первых круглых скобок вложенности быть не может, то начало можно сократить до того, как вы изначально пробовали, т.е. до \((.*?)\). Тогда еще надо будет не забыть поменять ссылку (?3)

Тест на regex101.com

UPD: Исходя из комментария "Круглые скобки содержат имя параметра, фигурные содержат параметры. Параметр может содержать другие параметры", в случае если поддержки рекурсии в вашем диалекте регулярных выражений нет можно применить:

 \((.*?)\){(.*)}

Первый захват не жадный, до первой встреченной круглой скобки, второй - жадный, захватит все до последней фигурной скобки, если других фигурных скобок в строке не будет, такого выражения будет достаточно

Mike
  • 44,087
2

В C# можно использовать балансирующие группы:

\((?<val1>(?>[^()]+|(?<o>\()|(?<-o>\)))*(?(o)(?!)))\){(?<val2>(?>[^{}]+|(?<w>{)|(?<-w>}))*(?(w)(?!)))}

См. демо

  • \( - открывающая скобка )
  • (?<val1>(?>[^()]+|(?<o>\()|(?<-o>\)))*(?(o)(?!))) - все, что между ( и )
  • \) - закрывающая скобка )
  • { - открывающая скобка {
  • (?<val2>(?>[^{}]+|(?<w>{)|(?<-w>}))*(?(w)(?!))) - все, что между { и }
  • } - закрывающая скобка }.

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