0

I'm trying to replace the ~ into | between the [ ] in the folowwing case:

{stackoverflow is a [cool~great~fast] website ~ Find your answers [easily~quickly] on stackoverflow}.

Note: The text between the [ ] can be multiline.

I've tried multiple regexs buth with no luck.

My closest call at the moment is:

$text = preg_replace("/\[(.*?)~(.*?)\]/i", "[$1|$2]", $text);

But that returns

{stackoverflow is a [cool~great|fast] website ~ Find your answers [easily|quickly] on stackoverflow}.
2
  • You should report which regular expressions you tried. It could be you make a mistake, and the regular expression is not correct. Commented Jul 3, 2010 at 22:48
  • The brackets can not be nested Commented Jul 3, 2010 at 22:59

3 Answers 3

2

You need to use one regex to find all strings in brackets and then another to replace the ~s in them. You can use preg_replace_callback to apply the ~-replacing regex to all the substrings in brackets like this:

preg_replace_callback('/\[[^\]]+\]/', function ($str) {
    return str_replace('~', '|', $str[0]);
}, $my_string)
Sign up to request clarification or add additional context in comments.

2 Comments

I would use str_replace instead of preg_replace in the callback, as invoking any preg function is fairly costly, so you could use str_replace('~', '|', $str[0]) instead and get the same effect.
@tsgrasser: Fair enough. Done.
2

simpler than you think

 echo preg_replace('/~(?=[^\[\]]*\])/s', '|', $a);

?= is a lookahead assertion and reads "followed by". That is, "a tilde followed by some non-brackets and then a closing bracket" - this matches only ~'s inside [ ]

1 Comment

This would also replace the ~ in "~la]", i.e. it does not require an opening bracket to occur before the tilde. That's probably not a problem though, so +1.
0

What are some examples of the regexes you've used? My immediate thought is that [] is tripping you up because that is used to match character classes. If you want to match [ or ] as a literal you must escape it with backslashes: \[ or \].

3 Comments

My closest call was preg_replace("/[(.*?)~(.*?)]/i", "[\1|\2]", $text); But I'm getting a weird character instead of the text.
the [] are escaped but stackoverflow removes the \ before it for some reason.
@brechtvhb: You get the funny character because \1 and \2 mean different things in double quotes than in single quotes. If I use single quotes and escape the brackets, I get correct results for simple cases with your regex. However it does not work when there are multiple ~s inside the brackets (only the first one in each bracket-pair will be replaced).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.