PHP - 正则表达式如何按条件替换字符串

时间:2015-05-23 12:06:12

标签: php regex replace conditional-statements

我有一个字符串:

{include "abc"}

{literal} 

function xyz() {

       "ok";

   }

{/literal}

{abc}

{123 }

我只想将所有{替换为{{}替换为}}而不是{literal}标记。结果将是:

{{include "abc"}}

{{literal}}

   function xyz() {

       "ok";

   }

   //... something contain { and }

{{/literal}}

{{abc}}

{123 }}

有人可以帮助我,谢谢

2 个答案:

答案 0 :(得分:2)

您可以使用此模式执行此操作:

$pattern = '~(?:(?<={literal})[^{]*(?:{(?!/literal})[^{]*)*+|[^{}]*)([{}])\K~'

$text = preg_replace($pattern, '$1', $text);

demo

模式细节:

~                       # pattern delimiter
(?:                     # non-capturing group
    (?<={literal})      # lookbehind: preceded by "{literal}"
                        # a lookbehind doesn't capture any thing, it is only a test
    [^{]*               # all that is not a {
    (?:
        {(?!/literal})  #/# a { not followed by "/literal}"
        [^{]*
    )*+                 # repeat as needed
  |                     # OR
    [^{}]*              # all that is not a curly bracket,
                        # (to quickly reach the next curly bracket)
)
([{}])                  # capture a { or a } in group 1
\K                      # discards all on the left from match result
                        # (so the whole match is empty and nothing is replaced,
                        # the content of the capture group is only added 
                        # with the replacement string '$1')
~

注意:此模式假定{literal}无法嵌套并始终关闭。如果{literal}可以保持未公开状态,则可以强制执行此默认行为:&#34;未结算的{literal}被视为已打开,直到字符串结束为止#34;

为此,您可以将捕获组更改为([{}]|(*COMMIT)(*F))。当第一个分支[{}]失败时,这意味着到达了字符串的结尾。 (*COMMIT)动词强制正则表达式引擎在模式失败后停止字符串中的所有研究,(*F)强制它失败。所以在{literal}之后保持不变。

答案 1 :(得分:0)

正则表达式:

(?s)(?<=\{literal\}).*?(?=\{\/literal\})(*SKIP)(*F)|([{}])

替换字符串:

\1\1

DEMO