Регулярное выражение для удаления внешних скобок

Я использовал этот /\(\s*([^)]+?)\s*\)/ regex для удаления внешних скобок с помощью функции PHP preg_replace (подробнее в моем предыдущем вопросе Regex соответствует любому символу, кроме конечных пробелов ) ,

Это отлично работает, когда имеется только одна пара скобок, но проблема в том, что, например, ( test1 t3() test2) становится test1 t3( test2) вместо test1 t3() test2 .

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

Итак, пример поведения достаточно хорош:

( test1 test2 ) => test1 test2

( test1 t3() test2 ) => (test1 t3() test2)

РЕДАКТИРОВАТЬ:

Я хотел бы сохранить обрезку бегущих пробелов внутри снятых скобок.

Solutions Collecting From Web of "Регулярное выражение для удаления внешних скобок"

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

 $arr = array('Foo ( test1 test2 )', 'Bar ( test1 t3() test2 )', 'Baz ((("Fdsfds")))'); foreach($arr as $str) echo "'$str' => " . preg_replace('/ \( \s* ( ( [^()]*? | (?R) )* ) \s* \) /x', '$1', $str) . "\n"; 

ВЫВОД:

 'Foo ( test1 test2 )' => 'Foo test1 test2' 'Bar ( test1 t3() test2 )' => 'Bar test1 t3() test2' 'Baz ((("Fdsfds")))' => 'Baz (("Fdsfds"))' 

Попробуй это

 $result = preg_replace('/\(([^)(]+)\)/', '$1', $subject); 

Обновить

 \(([^\)\(]+)\)(?=[^\(]+\() 

Сообщение RegEx

 " \( # Match the character “(” literally ( # Match the regular expression below and capture its match into backreference number 1 [^\)\(] # Match a single character NOT present in the list below # A ) character # A ( character + # Between one and unlimited times, as many times as possible, giving back as needed (greedy) ) \) # Match the character “)” literally (?= # Assert that the regex below can be matched, starting at this position (positive lookahead) [^\(] # Match any character that is NOT a ( character + # Between one and unlimited times, as many times as possible, giving back as needed (greedy) \( # Match the character “(” literally ) " 

Вы можете хотеть это (как я предполагаю, это то, что вы хотите изначально):

 $result = preg_replace('/\(\s*(.+)\s*\)/', '$1', $subject); 

Это получило бы

 "(test1 test2)" => "test1 test2" "(test1 t3() test2)" => "test1 t3() test2" "( test1 t3(t4) test2)" => "test1 t3(t4) test2"