PHP:如何以给定格式转换此句子

时间:2011-07-13 11:01:05

标签: php regex code-snippets

  

“[5 | 5] [提示|建议]一次难忘的旅程|五   建议一个不后悔的旅行| [5 |五] [提示|建议]为   一个[惊人的|不可思议的]旅行|五个[提示|建议]的一个   惊人的旅行“

  

“[5 | 5] [提示|建议]一次难忘的旅行〜五   建议一个不后悔的旅行〜[5 |五] [提示|建议]为   一个[惊人的|不可思议的]旅行〜五个[提示|建议]一个   惊人的旅行“

我可以使用str_replace("|", "~", $code),但问题是我不想将"|"转换为"~",如果它在"[ ]"之间。

6 个答案:

答案 0 :(得分:4)

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 :(得分:1)

此正则表达式应该执行/^(?<!\[.)\|(?!].)/

之后的操作

preg_replace和klabamo结合,你得到了它:)

现在看起来好多了!

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

答案 2 :(得分:1)

$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]]),它就是正确的。

  

(?<=^|\]) - 从字符串的开头或]后面开始   ([^\[]*?) - 捕获任何数量不是[的字符   \| - 我们要替换的角色   ([^\[]*?) - 捕获任意数量的非[字符(再次)
  (?=\[|$) - 在字符串末尾或[

之前停止匹配

答案 3 :(得分:0)

您可以先用str_replace替换all,然后重新替换[]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);

答案 4 :(得分:0)

如果您知道方括号将始终保持适当平衡且从不嵌套,那么您只需要一个简单的前瞻:

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

<强> demo

在竖线字符后立即开始,前瞻扫描下一个右方括号。如果它找到一个没有首先看到方括号,那么管道必须在一对括号内。没有必要检查带有lookbehind的开括号,这很好,因为PHP(像大多数正则表达式)不支持可变宽度的lookbehinds。

我使用否定前瞻,但肯定前瞻也可以使用:

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

<强> demo

请注意,如果它是列出的第一个字符(或者,在这种情况下,是否为^之后的第一个字符),则不必在字符类中转义右方括号。因此,奇怪的[^][]为“不是方括号”。 *+possessive quantifier

如果可以嵌套方括号,则应该忘记正则表达式并使用@RiaD's solution。它仍然可以使用正则表达式,但它会更复杂。

答案 5 :(得分:-1)

您可以使用PHP preg_match并与str_replace结合使用 - 我不是正则表达式专家,因此我无法为您编写任何内容。

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