If you know that square brackets will always be correctly balanced and never be nested, you will need a simple look:
$after = preg_replace('/\|(?![^][]*+\])/', '~', $before);
demonstration
Starting immediately after the pipe symbol, lookahead scans the next right square bracket. If he finds one without first seeing the left square bracket, the pipe should be inside a pair of brackets. There is no need to check the opening bracket with lookbehind, which is good because PHP (like most varieties of regular expressions) does not support lookbehind of variable width.
I used a negative forecast, but a positive result could also work:
$after = preg_replace('/\|(?=[^][]*+(?:\[|$))/', '~', $before);
demonstration
Note that there is no need to leave the right square bracket in the character class if this is the first character specified (or, as in this case, the first character after the negation ^ ). So the odd [^][] for "not a square bracket". And *+ is an possessive quantifier .
If square brackets can be nested, you should forget about regular expressions and go to the @RiaD solution . It may still be possible to use regular expressions, but it will be much more complicated.
source share