Я думаю, что самый простой способ сделать это - несколько проходов. Используйте регулярное выражение вроде:
\[\[(?:[^\[\]]*\|)?([^\[\]]+)\]\]
Это заменит строки параметров, чтобы дать вам последний вариант из группы. Если вы будете запускать его несколько раз, пока он больше не будет совпадать, вы должны получить правильный результат (первый проход заменит [[out1 [[inside]] out2]] на [[out1insideout2]], а второй отбросит скобки.
Редактировать 1 : В качестве объяснения,
\[\[ # Opening [[
(?: # A non-matching group (we don't want this bit)
[^\[\]] # Non-bracket characters
* # Zero or more of anything but [
\| # A literal '|' character representing the end of the discarded options
)? # This group is optional: if there is only one option, it won't be present
( # The group we're actually interested in ($1)
[^\[\]] # All the non-bracket characters
+ # Must be at least one
) # End of $1
\]\] # End of the grouping.
Редактировать 2 : Изменено выражение, чтобы игнорировать ']', а также '[' (работает немного лучше).
Редактировать 3 : Нет необходимости знать количество вложенных скобок, так как вы можете сделать что-то вроде:
$oldtext = "";
$newtext = $text;
while ($newtext != $oldtext)
{
$oldtext = $newtext;
$newtext = preg_replace(regexp,replace,$oldtext);
}
$text = $newtext;
По сути, это продолжает выполнять регулярное выражение замены до тех пор, пока вывод не станет таким же, как ввод.
Обратите внимание, что я не знаю PHP, поэтому, возможно, в приведенном выше тексте есть ошибки синтаксиса.