开发者

PHP: how to convert this sentence in given format

"[5|f开发者_开发问答ive] [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"

to

"[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"

I could use str_replace("|", "~", $code) but the issue is I don't want to convert "|" into "~" if it is between "[ ]".


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]='~';
}


$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 as long as you don't nest brackets ([foo [bar]]).

(?<=^|\]) - start at the beginning of the string or following a ]
([^\[]*?) - capture any number of characters that aren't a [
\| - the character we want to replace
([^\[]*?) - capture any number of characters that aren't a [ (again)
(?=\[|$) - stop matching at the end of the string or before a [


This regex should do what you're after /^(?<!\[.)\|(?!].)/

Combine with preg_replace and klabamo you've got it :)

This now seems to work a lot 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;


You can first replace all with str_replace and then re-replace those which are inside [] (Demo):

$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);


If you know the square brackets will always be properly balanced and never nested, a simple lookahead is all you need:

$after = preg_replace('/\|(?![^][]*+\])/', '~', $before);

demo

Starting immediately after the pipe character, the lookahead scans for the next right square bracket. If it finds one without seeing a left square bracket first, the pipe must be inside a pair of brackets. There's no need to check for the opening bracket with a lookbehind, which is good, because PHP (like most regex flavors) doesn't support variable-width lookbehinds.

I used a negative lookahead, but a positive lookahead could work, too:

$after = preg_replace('/\|(?=[^][]*+(?:\[|$))/', '~', $before);

demo

Note that it isn't necessary to escape the right square bracket in a character class if it's the first character listed (or, as in this case, the first character after the negating ^). Thus, the odd-looking [^][] for "not a square bracket". And *+ is a possessive quantifier.

If square brackets can be nested, you should forget about regexes and go with @RiaD's solution. It might still be possible to use regexes, but it will be a lot more complicated.


You could potentially use PHP preg_match and combine with str_replace - I am not a regexp expert so I won't be able to write anything for you.

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜