Если вы знаете, что квадратные скобки всегда будут правильно сбалансированы и никогда не будут вложены, все, что вам нужно, это простой взгляд:
$after = preg_replace('/\|(?![^][]*+\])/', '~', $before);
демо
Начиная сразу после символа трубы, смотрит в поисках следующей правой квадратной скобки. Если он находит его, не увидев сначала левую квадратную скобку, труба должна быть внутри пары скобок. Нет необходимости проверять открывающую скобку с lookbehind, что хорошо, потому что PHP (как и большинство разновидностей regex) не поддерживает lookbehinds переменной ширины.
Я использовал отрицательный прогноз, но положительный прогноз тоже мог бы работать:
$after = preg_replace('/\|(?=[^][]*+(?:\[|$))/', '~', $before);
демо
Обратите внимание, что нет необходимости экранировать правую квадратную скобку в классе символов, если это первый перечисленный символ (или, как в этом случае, первый символ после отрицания ^
). Таким образом, выглядит странно [^][]
для «не квадратной скобки». И *+
является собственническим квантификатором .
Если квадратные скобки могут быть вложенными, вам следует забыть о регулярных выражениях и использовать решение @ RiaD . Возможно, еще можно использовать регулярные выражения, но это будет намного сложнее.