【问题标题】:PHP - How can regex replace a string by conditionPHP - 正则表达式如何按条件替换字符串
【发布时间】:2015-05-23 12:06:11
【问题描述】:

我有一个字符串:

{include "abc"}

{literal} 

function xyz() {

       "ok";

   }

{/literal}

{abc}

{123 }

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

{{include "abc"}}

{{literal}}

   function xyz() {

       "ok";

   }

   //... something contain { and }

{{/literal}}

{{abc}}

{123 }}

有人可以帮助我,谢谢

【问题讨论】:

  • 你有什么尝试吗?
  • 只是我,还是这是另一个 X-Y 问题?你为什么要为此转向正则表达式?在我看来,您正在尝试解析某些内容
  • 哦,我尝试解析 smarty :)

标签: php regex replace conditional-statements


【解决方案1】:

你可以用这个模式来做:

$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} 可以保持未关闭状态,则可以强制执行此默认行为:“未关闭的{literal} 被视为打开直到字符串结尾”

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

【讨论】:

    【解决方案2】:

    正则表达式:

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

    替换字符串:

    \1\1
    

    DEMO

    【讨论】:

    • 非常感谢,这对我有用。我认为你是正则表达式的大师:D
    猜你喜欢
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多