【问题标题】:PHP: how to convert this sentence in given formatPHP:如何将这句话转换为给定的格式
【发布时间】:2011-10-04 09:43:02
【问题描述】:

"[5|five] [提示|建议] 难忘的旅行|Five 一次不遗憾的旅行的建议|[5|五] [提示|建议] 一次 [amazing|incredible] 旅行|五个 [tips|suggesions] for an 惊人的旅行”

"[5|five] [Tips|Suggestions] 难忘的旅行~5 推荐一次不后悔的旅行~[5|5] [tips|suggestions] for 一次 [amazing|incredible] 旅行~五个 [tips|suggesions] for an 惊人的旅行”

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

【问题讨论】:

  • 你的句子是作为任何变量的输入吗?

标签: php regex code-snippets


【解决方案1】:

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

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

demo

在管道字符之后立即开始,前瞻扫描下一个右方括号。如果它在没有首先看到 left 方括号的情况下找到一个,则管道必须位于一对括号内。无需使用后视检查左括号,这很好,因为 PHP(像大多数正则表达式一样)不支持可变宽度后视。

我使用了 negative 前瞻,但 positive 前瞻也可以工作:

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

demo

请注意,如果字符类中的右方括号是列出的第一个字符(或者,在本例中,否定^ 之后的第一个字符),则无需转义它。因此,奇怪的[^][] 表示“不是方括号”。而*+possessive quantifier

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

【讨论】:

  • 我刚刚下载并尝试过,它真的很棒!非常感谢您的帮助。
【解决方案2】:

这个正则表达式应该做你在/^(?<!\[.)\|(?!].)/之后的事情

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;

【讨论】:

  • 不,它不起作用。您的“之前”字符串与 OP 的“之后”字符串相同;您的代码不会改变任何东西。
【解决方案3】:
$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]]) 就会正确。

(?&lt;=^|\]) - 从字符串的开头开始或在]之后
([^\[]*?) - 捕获任意数量的不是[的字符
\| - 我们的字符想要替换
([^\[]*?) - 捕获任意数量的不是 [ 的字符(再次)
(?=\[|$) - 在字符串末尾或 [ 之前停止匹配

【讨论】:

  • 这肯定有点矫枉过正?
  • @James 我很累,所以我可能会遗漏一些东西,但对于示例来说,您的解决方案似乎无法正常运行,因为它无法匹配 @ 之间的任意数量的字符987654332@ 和|。这工作正常。
  • @James:您的正则表达式在 preg_replace 中不起作用,Jeremy 的则起作用。为了减少开销,在我的正则表达式中,我正在处理否定。
  • 我已经更新了正则表达式并提供了一个示例。它适用于这个测试用例。
【解决方案4】:

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

【讨论】:

  • 是的,这个也很好用,谢谢!摇摆!!
【解决方案5】:

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

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

【讨论】:

    【解决方案6】:
    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]='~';
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-23
      • 2020-12-26
      • 2020-09-05
      • 2019-06-01
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多