Вы можете сделать это с помощью цикла for и массива, действующего как стек. Когда вы найдете открытую скобку, нажмите на стопку, и когда вы найдете закрывающую скобку, выскочившую из стопки. Длина стека скажет вам, если вы должны заменить текущую скобку.
$stack = array();
$str = "Arman; Dario (10040 Druento (Turin), IT)";
$out = "";
for ($i = 0, $l = strlen($str); $i < $l; ++$i) {
if ($str[$i] == "(") {
$stack[] = true;
if (count($stack) % 2) { // alternate between ( and [
$out .= "(";
} else {
$out .= "[";
}
} else if ($str[$i] == ")") {
if (count($stack) % 2) {
$out .= ")";
} else {
$out .= "]";
}
array_pop($stack);
} else {
$out .= $str[$i];
}
}
Вот несколько примеров ввода и вывода:
Arman; Dario (10040 Druento (Turin), IT)
Arman; Dario (10040 Druento [Turin], IT)
a ( b ( c ( d ) ) e )
a ( b [ c ( d ) ] e )
a (b (c) (d) (e) )
a (b [c] [d] [e] )
a (b (c (d) (e) (f)))
a (b [c (d) (e) (f)])
Это не особенно эффективный алгоритм (построение строкового char с помощью char), и он может быть немного умнее с несопоставленными скобками, но в любом случае ...