如果不匹配,请忽略第二场比赛的HTML

时间:2011-09-20 08:34:20

标签: php regex preg-replace

我正在写一个应该执行以下操作的正则表达式:

== Text ==
Other text
==     Text==

变为

<h2>Text</h2>
<p>Other text</p>
<h2>Text</h2>

我差不多了,问题是这就是我现在得到的:

<h2>Text</h2>
<p>Other text</p>
<h2>Text</h2>
<p></p>

尽管文字后面的标题不太可能,但我想修复它至少是为了学习目的。

这是我的功能:

preg_replace('/== *(.*?) *==([^=]*)/m', 
             '<h2>$1</h2>
              <p>$2</p>
             ', '== Text ==
                 Other text
                 ==     Text==');

基本上,如果<p></p>为空,我想忽略$2部分。

欢迎任何其他提示/改进,我想学习:)

2 个答案:

答案 0 :(得分:1)

您需要一个简单的条件来阻止显示空的<p>标记。虽然我不建议这样做,但是插入这个简单if的最简单方法是使用/e正则表达式修饰符preg_replace

preg_replace('/== *(.*?) *==([^=]*)/me', 
             '"<h2>$1</h2>".(trim("$2") == ""?"":"<p>$2</p>")',
             '== Text ==
                 Other text
              ==     Text==');

这个修饰符使替换字符串在进行替换之前被评估为PHP代码,因此您可以轻松地在其中放入一个小条件。

<强> See it in action

另一个选择是使用preg_replace_callback,这实际上只是你现在将代码编写为单独的函数时的想法。这是更好的恕我直言,因为它使代码更清晰。

最后要注意的是,如果您打算添加更多格式化选项,您可能需要考虑将解析分解为多个步骤,并且可能一次处理一行,因为正则表达式不是为处理这种处理而设计的。你可以将它强制到某一点,但随后它会很快变得非常难以维护。

答案 1 :(得分:1)

如何分两步完成:

首先在不以==开头/结尾的每一行周围添加段落标记:

$firststep = preg_replace('/^(?![ \t]*==.*==[ \t]*$).+/m', '<p>\0</p>', $subject);

然后在使用==开始/结束的每一行周围添加标题标记:

$result = preg_replace('/^[ \t]*==[ \t]*(.*?)[ \t]*==[ \t]*$/m', '<h2>\1</h2>', $firststep);