Вы должны использовать сбалансированные группы:
@foreach\([^)]*\)\s*{(?>(?<open>@foreach\([^)]*\)\s*{)|@{[^}]*}|[^}@]+|(?<-open>}@))*(?(open)(?!))}@
Идея заключается в том, чтобы определить именованный захват, который работает как счетчик. Когда найденная подстрока найдена, счетчик увеличивается, когда найденная подстрока найдена, счетчик уменьшается. (?(open)(?!))
заставляет шаблон сбой, если счетчик не равен нулю.
@foreach\([^)]*\)\s*{
(?> # possible content in a foreach
(?<open>@foreach\([^)]*\)\s*{) # increment the counter
|
@{[^}]*}
|
[^}@]+ # all that is not a @ or } (can be improved to be more flexible)
|
(?<-open>}@) # decrement the counter
)*
(?(open) # conditional statement (if "open" is not null)
(?!) # then make fail the pattern (with the always false assertion `(?!)`)
)
}@
demo
Что ваш ожидаемый результат? –
'Я хочу 'не вопрос. – Jonesopolis
Вы хотите проверить наличие вложенных парантез? –