PHP: how to convert this sentence to a given format

"[5 | 5] [Tips | Suggestions] for an unforgettable trip | Five suggestions for an unheard of trip | [5 | five] [tips | suggestions] for an [amazing | incredible] trip | Five [tips | suggestions] for an amazing trip"

to

"[5 | 5] [Tips | Suggestions] for an unforgettable trip ~ Five suggestions for an indescribable trip ~ [5 | five] [tips | suggestions] for an [amazing incredible] trip ~ Five [tips | suggestions] for an amazing trip"

I could use str_replace("|", "~", $code) , but the problem is that I do not want to convert "|" in "~" if it is between "[ ]" .

+4
source share
6 answers
 for($i=0,$s=strlen($str),$c=0;$i<$s;++$i){ if($str[$i]=='[')++$c; elseif($str[$i]==']')--$c; elseif(!$c && $str[$i]=='|')$str[$i]='~'; } 
+4
source

This regular expression should do what you do after /^(?<!\[.)\|(?!].)/

Combine with preg_replace and klabamo, you have it :)

Now it works much better!

 $sentence = "[5|five] [Tips|Suggestions] for an Unforgettable Trip~Five suggestions for a un-regret able Trip~[5|five] [tips|suggestions] for an [amazing|incredible] Trip~Five [tips|suggestions] for an astonishing Trip"; $newSentence = preg_replace("/^(?<!\[.)\|(?!].)/", "~", $sentence); echo $newSentence; 
+1
source
 $in = "[5|five] [Tips|Suggestions] for an Unforgettable Trip|Five suggestions for a un-regret able Trip|[5|five] [tips|suggestions] for an [amazing|incredible] Trip|Five [tips|suggestions] for an astonishing Trip"; $out = preg_replace('/(?<=^|\])([^\[]*?)\|([^\[]*?)(?=\[|$)/s', '\1~\2', $in); 

The regular expression works as follows and will be correct if you do not insert brackets ( [foo [bar]] ).

(?<=^|\]) - start at the beginning of a line or after ]
([^\[]*?) - capture any number of characters that are not [
\| - the character we want to replace ([^\[]*?) - capture any number of characters that are not [ (again)
(?=\[|$) - stop the match at the end of the line or before [

+1
source

You can replace everything with str_replace first and then replace those inside [] ( demo ) again:

 $subject = '[5|five] [Tips|Suggestions] for an Unforgettable Trip|Five suggestions for a un-regret able Trip|[5|five] [tips|suggestions] for an [amazing|incredible] Trip|Five [tips|suggestions] for an astonishing Trip'; $result = str_replace('|', '~', $subject); $pattern = '((\[[^\]]*)~([^\[]*\]))'; $result = preg_replace($pattern, '$1|$2', $result); var_dump($subject, $result); 
0
source

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.

0
source

You could use PHP preg_match and combine with str_replace - I am not a regular expression expert, so I won’t be able to write anything for you.

http://php.net/manual/en/function.preg-match.php

-1
source

All Articles