Php 忽略第二个匹配';如果不匹配,则返回HTML

Php 忽略第二个匹配';如果不匹配,则返回HTML,php,regex,preg-replace,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<

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

== 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==');
preg_replace('/==*(.*?*==([^=]*))/m',
'$1
2美元

“,”==文本== 其他文本 ==文本==');
所以基本上,如果
$2
为空,我想忽略

部分


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

您需要一个简单的条件来防止出现空的
标记。虽然我通常不建议这样做,但插入这个简单的
if
的最简单方法是使用
/e
regex修饰符:

preg_replace('/==*(.*?*==([^=]*))/me',
“$1”。(修剪(“$2”)=”?:“$2

”, '==文本== 其他文本 ==文本==');
此修饰符使替换字符串在进行替换之前作为PHP代码进行计算,因此您可以轻松地在其中放入一个小条件

另一种选择是使用,这实际上与您现在将代码作为单独的函数编写的想法相同。这是更好的IMHO,因为它使代码更清晰


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

分两步执行如何:

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

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

您应该废弃这个正则表达式并逐行解析输入。将防止您以后发疯。因为如果您以后想添加更多选项,您将无法添加。我将如何进行此操作,将正则表达式拆分为匹配
=*(.*?*)*==
或不匹配,如果它不只是添加

或其他内容?我添加了一个正确的答案,检查一下。如果这是用于标记或Wiki标记,则有用于此的解析器/生成器,因此您不必手动完成。这当然是一个很好的解决方案,但我不能相信我的客户总是将标题标记放在单独的行上。这是一个很好的修改器,我当然会研究
preg\u replace\u callback
,因为您提供的原因,我不希望我的PHP代码在函数中突出显示为字符串。不过,另一个问题是,如果正则表达式不是为这种处理而设计的,有没有更好的方法?或者你只是说我应该小心我走多远。据我所知,几乎每个论坛(以及这个网站)都使用BBCode和变体,它们是用正则表达式编写的,对吗?@Kokos:对,但它们不会试图同时用一个正则表达式解析所有BBCode。这就是我所说的“将解析分解为多个步骤”。啊,是的,我没打算这么做。我更想知道的是“一次处理一行”,因为这总是期望人们把他们的东西放在不同的行上。你帮了我很多,教了我一些东西,干杯!
$result = preg_replace('/^[ \t]*==[ \t]*(.*?)[ \t]*==[ \t]*$/m', '<h2>\1</h2>', $firststep);