PHP: как преобразовать это предложение в заданный формат - PullRequest
4 голосов
/ 13 июля 2011

"[5 | пять] [Советы | Предложения] для незабываемой поездки | Пять предложений для незабываемой поездки | [5 | пять] [советы | предложения] для [удивительной | невероятной] поездки| Пять [советов | предложений] для удивительной поездки "

до

" [5 | пять] [Советы | Предложения] для незабываемой поездки ~ Пять предложений дляПоездка без сожаления ~ [5 | пять] [советы | предложения] для [удивительной | невероятной] поездки ~ Пять [советы | предложения] для удивительной поездки "

Я мог бы использовать str_replace("|", "~", $code) но проблема в том, что я не хочу конвертировать "|" в "~", если он находится между "[ ]".

Ответы [ 6 ]

4 голосов
/ 13 июля 2011
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]='~';
}
1 голос
/ 13 июля 2011
$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);

Регулярное выражение работает следующим образом и будет правильным до тех пор, пока вы не вложите скобки ([foo [bar]]).

(?<=^|\]) - начало в началестрока или после ]
([^\[]*?) - захватить любое количество символов, которые не являются [
\| - символ, который мы хотим заменить
([^\[]*?) - захватить любойколичество символов, которые не являются [ (снова)
(?=\[|$) - прекратить сопоставление в конце строки или перед [

1 голос
/ 13 июля 2011

Это регулярное выражение должно делать то, что вы после /^(?<!\[.)\|(?!].)/

В сочетании с preg_replace и клабамо у вас это получится:)

Теперь это выглядит намного лучше!

$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;
0 голосов
/ 13 июля 2011

Если вы знаете, что квадратные скобки всегда будут правильно сбалансированы и никогда не будут вложены, все, что вам нужно, это простой взгляд:

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

демо

Начиная сразу после символа трубы, смотрит в поисках следующей правой квадратной скобки. Если он находит его, не увидев сначала левую квадратную скобку, труба должна быть внутри пары скобок. Нет необходимости проверять открывающую скобку с lookbehind, что хорошо, потому что PHP (как и большинство разновидностей regex) не поддерживает lookbehinds переменной ширины.

Я использовал отрицательный прогноз, но положительный прогноз тоже мог бы работать:

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

демо

Обратите внимание, что нет необходимости экранировать правую квадратную скобку в классе символов, если это первый перечисленный символ (или, как в этом случае, первый символ после отрицания ^). Таким образом, выглядит странно [^][] для «не квадратной скобки». И *+ является собственническим квантификатором .

Если квадратные скобки могут быть вложенными, вам следует забыть о регулярных выражениях и использовать решение @ RiaD . Возможно, еще можно использовать регулярные выражения, но это будет намного сложнее.

0 голосов
/ 13 июля 2011

Вы можете сначала заменить все на str_replace, а затем снова заменить те, которые находятся внутри [] ( Демо ):

$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 голосов
/ 13 июля 2011

Вы могли бы потенциально использовать PHP preg_match и объединиться с str_replace - я не эксперт по регулярным выражениям, поэтому я не смогу ничего написать для вас.

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

...