正则表达式匹配并替换高级

时间:2011-06-15 22:51:06

标签: php regex wordpress

我正在尝试编写一个小的WordPress插件来支持一些迁移的内容。

语法高亮显示器期望(正确突出显示):

<pre lang='something'>
  <code>
    The code...
  </code>
</pre>

但是,我的降价代码具有以下内容:

<pre>
  <code>
    :::something
    The code...
  </code>
</pre>

我想你可以看到它的发展方向。我想要实现的是:

    应删除
  1. :::something,并将<pre>标记更新为<pre lang="something">
  2. 如果:::something不存在,则<pre>代码应为<pre lang="plain">
  3. 每页可能有多次需要更新。
  4. 实现上述功能的PHP函数如何?

    function set_syntax_lang($content) {
      // Do stuff here
      return $new_content;
    }
    

    到目前为止我收集的是这个正则表达式:

    /<pre.*>\s*<code>\s*:::(\w)/
    

    这甚至让我使用preg_match实际语法指示符(something),但我不知道如何正确更新pre - 标记。

    自从我编写PHP并且正则表达式并不是我的强项之后已经很长时间了。所以所有的帮助都表示赞赏。

3 个答案:

答案 0 :(得分:1)

发现:::某事

preg_replace( '/<pre(.*>\s*<code>\s*):::(\w+)/U', '<pre lang="$2"$1' , $html );

这是一个边缘案例。但通常我应该建议你不要使用正则表达式为html(bobince某人?)。

另外,下次尝试对你的问题不要过分。我花了更多时间来读你而不是写这个答案。

查找没有::: something

的代码
preg_replace( '/<pre(.*>\s*<code>\s*)(?!:::\w+)/U', '<pre lang="plain"$1' , $html );

修复<code>

preg_replace( array( '/(<pre.*>)\s*<code>/U' , '/<\/code>\s*(<\/pre>)/U' ),
              '$1' , $html );
//> Completly untested

答案 1 :(得分:1)

您在回答的步骤中回答了大部分问题。将其分解为这些块 - 首先查看您是否:::something,然后更新您的<pre>标记并重播。

如果你使用DOM而不是正则表达式,你会有更轻松的时间。它将使<pre><code>标签的导航工作变得非常简单。正如已经多次说过的那样,html不是常规语言,因此正则表达式无法正确解析它。即使是有限的HTML子集,它也不是正确的工具。一旦您使用DOM在:::something<code>之间获取文字,</code>的正则表达式就会微不足道:/:::(\w+)/

答案 2 :(得分:1)

首先,我跑过一些观点:

/<pre.*>\s*<code>\s*:::(\w)/
     ^ 

根据您的问题,如果您使用:::something,那里绝不会有空格。但是你把它添加到正则表达式中。我想知道为什么。

/<pre.*>\s*<code>\s*:::(\w)/
                         ^ 

如果语言说明符大于一个字符(我假设),则必须将其写入正则表达式,如\w+一个或多个字母。

其余的看起来很像你已经拥有的一切。可能不是替代品:

$result = preg_replace( '((<pre)(>\s*<code>\s*):::(\w+))', '$1 lang="$3"$2' , $subject );

希望这有帮助。