Dawno już nie siedziałem w PHP więc napiszę Ci to w JS, ale myślę, że łatwo przerobisz sobie na PHP:
const str = 'xxx {text text} abc {jakiś tekst} kkk';
//Przykład zły:
str.replace( /\{.+\}/g, '{nowy}' )
"xxx {nowy} kkk"
//Przykład dobry:
str.replace( /\{.+?\}/g, '{nowy}' )
"xxx {nowy} abc {nowy} kkk"
Chodzi o coś takiego? Rozumiem, że chcesz wyszukać wszystkie { dowolny tekst } i zamienić na { nowy }, przy czym dla wszystkich "dowolnych" nowy jest taki sam?
W powyższych przykładach słowo klucz to kwantyfikator niezachłanny - zauważ dodatkowy "?" po kwantyfikatorze "+". Bez tego regexp dopasowuje pierwszy nawias "{" następnie różne znaki i ostatni nawias, włączając w to również nawiasy wewnętrzne. Kwantyfikator niezachłanny działa inaczej, po napotkaniu "{" rozpoczyna szukanie dalszych znaków dalej od lewej do prawej przez co może dopasować wszystkie elementy.
Twój wzorzec dopasowuje coś zupelnie innego:
/{+\[a-zA-Z0-9_]+\}/
{+ //co najmniej jeden "{"
\[ //dosłowne dopasowanie nawiasu "["
a-zA-Z0-9_ //dosłowne dopasowanie takiego ciągu znakowego
]+ //co najmniej jeden nawias "]"
\} //dokładnie jeden nawias "}"
//Testy w JavaScript:
/{+\[a-zA-Z0-9_]+\}/.test('{[a-zA-Z0-9_]}'); //true
/{+\[a-zA-Z0-9_]+\}/.test('{{{{{[a-zA-Z0-9_]]]]]]}'); //true
/{+\[a-zA-Z0-9_]+\}/.test('{text}'); //false
Zobacz czy mój wzorzec (z kwantyfikatorem niezachłannym) spełnia Twoje oczekiwania i daj znać gdyby dalej coś było nie tak - wtedy też podaj dane wejściowe, na których chcesz inne zachowanie.
Aha, i w Twoim wzorcu nie dopasujesz też polskich liter ąę itp. bo nie mieszczą się one w a-z :)