【问题标题】:How to match something like shortcode that repeats and contains whatever including new lines如何匹配重复并包含包括新行在内的任何内容的短代码
【发布时间】:2014-06-20 18:00:23
【问题描述】:

我正在尝试通过 preg_replace_callback 函数处理类似 shrotcode 的内容:

$new_content = preg_replace_callback("|\[BLOCK\s?(TYPE=[0-9a-z\/]+)?\s?(TEXT=[a-z]+)?\s?(LAST)?\s?\]((?:(?!BLOCK).)*)\[\/BLOCK\]|","block",$content);

主题($content)例如是这样的:

[BLOCK TYPE=1/2 TEXT=right LAST]
<ul><li>something</li>
</ul>
[/BLOCK]
[BLOCK TYPE=1/2 TEXT=right LAST][NEXTSHORTCODE=something][/BLOCK]
[BLOCK TYPE=1/2 TEXT=right LAST]123[/BLOCK]

我遇到了一个问题:

函数 preg_replace_callback 匹配整个主题(从 BLOCK 到最后一个 /BLOCK),而不是 /BLOCK 的第一次出现。 我想从简码的内部内容中排除字符串 BLOCK ((?:(?!BLOCK).)*) 来解决它,但它不适用于换行等其他字符。

你可以在这里看到我的尝试:http://rubular.com/r/0AqadXVdON

感谢您的建议,抱歉英语不好。

【问题讨论】:

    标签: php regex preg-replace-callback non-greedy


    【解决方案1】:

    您需要为结束标记使用所谓的惰性匹配表达式。

    您的正则表达式以 \[\/BLOCK\] 结尾。

    尝试用\[\/BLOCK\]? 结束它。这将使它匹配它找到的第一次出现(惰性)而不是最后一次出现(贪婪)。

    【讨论】:

      【解决方案2】:

      补充一下 Ollie 所说的,如果您不关心 BLOCK 中的 TYPE 和其他引用,而只想替换所有块,则可以使用以下简单的方法:

      $regex = "~(?s)\[BLOCK.*?/BLOCK]~";
      $new_content = preg_replace_callback($regex, $block, $subject);
      function block($m) {
        // replace magic
        return $something;
      }
      

      【讨论】:

        【解决方案3】:

        您缺少m 开关。

        试试这个:

        \[BLOCK\s?(TYPE=[0-9a-z\/]+)?\s?(TEXT=[a-z]+)?\s?(LAST)?\s?\]((?:(?!BLOCK).)*)\[\/BLOCK\]

        演示

        http://rubular.com/r/7ijXdrhERE

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-19
          • 2017-02-26
          • 2010-09-23
          相关资源
          最近更新 更多