我正在开发一个论坛系统,它像BBCode一样解析[b]some bold text[/b],并在通过[b]some bold text[/b]输出时对其应用HTML格式。我所有的表达式都能工作,但我很难弄清楚如何处理某个场景,特别是关于嵌套引号块。
在论坛上,您可能有一个用户引用另一个用户。我已经成功地使用以下方法格式化了这个文件:
#\[quote="(.*?);(\w*?)"\]\s*(.*?)\s*\[\/quote\]#
并调用preg_replace()将其替换为:
<blockquote id="quote-$2"><p>$3<br> - $1</p></blockquote>,这里是工作实例。
在一个实际的例子中,您可能在论坛上看到一个用户Stan想引用John,并将其添加到文本区域以供提交:
[quote="John;2"]John's sentence[/quote]
____________
Stan's reply但是,如果约翰在他的帖子中引用了玛丽的话,会发生什么呢?
[quote="John;2"][quote="Mary;1"]Mary's sentence[/quote]John's sentence[/quote]
____________
Stan's reply我的正则表达式将捕获除最后一个[/quote]之外的所有内容,但即使能够捕获整个字符串,我也不确定如何格式化它。理想情况下,我希望输出如下所示:
"Mary's sentence"
- Mary
"John's sentence"
- John
__________________________
Stan's reply在HTML中:
<blockquote id="quote-2">
<blockquote id="quote-1"><p>"Mary's sentence"<br> - Mary</p></blockquote>
<p>"John's sentence"<br> - John</p>
</blockquote>
<p>Stan's reply</p>我是否可以使用regex捕获和格式化重复嵌套标记?如果有100个嵌套引号块呢?显然,我可以写一个非常长且重复的表达式(这当然会有局限性),但是必须有更好的方法来解决这个问题。还有别的方法我应该用吗?
如果是类似的问题已经存在。,我很抱歉,但是我已经看过很多关于这方面的问题,并且仍然不确定我应该采取哪种方法。
发布于 2018-07-23 07:58:14
这样做的目的是确保你只匹配最里面的BB标签。在[quote和[/quote]之间匹配不包含其他[quote=的所有文本,然后替换,直到找不到匹配为止。它还基于一个假设,即您的实际标记内容中没有[quote=,但在大多数情况下,这是正确的。另一个假设是,属性是"-quoted,不能有其他双引号。
所以,你可以用
$s = '[quote="John;2"][quote="Mary;1"]Mary\'s sentence[/quote]John\'s sentence[/quote]';
$repl = '<blockquote id="quote-$2"><p>$3 <br> - $1</p></blockquote>';
$reg = '~\[quote="([^"]*);(\w*)"]\s*((?:(?!\[quote=).)*?)\s*\[/quote]~si';
while (preg_match($reg, $s)) {
$s = preg_replace($reg, $repl, $s);
}
echo $s;
// => <blockquote id="quote-2"><p><blockquote id="quote-1"><p>Mary's sentence <br> - Mary</p></blockquote>John's sentence <br> - John</p></blockquote>见PHP演示。判断力
'~\[quote="([^"]*);(\w*)"]\s*((?:(?!\[quote=).)*?)\s*\[/quote]~si'见regex演示。
详细信息
\[quote=" -一个文字子字符串([^"]*) -捕获组1:除"以外的任何0+字符; -一个冒号(\w*) -捕获组2: 0+字母表"] -一个文字子字符串\s* - 0+白空间((?:(?!\[quote=).)*?) -捕获组3:任何字符,尽可能少,不启动[quote=文本\s* - 0+白空间\[/quote] -一个文字[/quote]子字符串。漂亮的打印是一项额外的任务,还有这里提到的几个解决方案.
https://stackoverflow.com/questions/51471701
复制相似问题