preg_replace : 从 BBCode 获取另一个 html 标签内的 html 标签
preg_replace : getting a html tag inside an other html tag from BBCode
所以我正在尝试制作一个 php 函数来从 BBCode-style 表单中获取 HTML 标签。事实上,我可以使用 preg_replace 轻松获得标签。但是当我在同一个 bbcode 中有一个 bbcode 时,我遇到了一些麻烦...
像这样:
[blue]My [black]house is [blue]very[/blue] beautiful[/black] today[/blue]
所以,当我 "parse" 它时,我总是保留蓝色的 bbcode。像 :
My house is [blue]very[/blue] beautiful today
除了第一个蓝色标签内的黑色标签内的蓝色标签外,所有内容都是彩色的。
我该怎么做?
有了更多信息,我试过了:
Regex: "/\[blue\](.*)\[\/blue\]/si" or "/\[blue\](.*)\[\/blue\]/i"
Getting : "My house is [blue]very[/blue] beautiful today"
Regex : "/\[blue\](.*?)\[\/blue\]/si" or "/\[blue\](.*)\[\/blue\]/Ui"
Getting : "My house is [blue]very beautiful today[/blue]"
我必须循环 preg_replace 吗? regex-style 没有循环的方法吗?
感谢您的关心。 :)
不应该在产品上重新发明轮子,而是选择 well-tested 插件是正确的。但是,如果您正在试验或从事宠物项目,请务必继续试验,享受乐趣并在过程中获得重要知识。
话虽如此,您可以尝试使用正则表达式。我会在下面为你分解。
(\[(.*?)\])(.*?)(\[/\])
哲学
在像这样解析标记时,您实际寻求的是 将标签与其成对 .
进行匹配
因此,您可以采取的一种干净的方法是 运行 一个循环,并且 每次都捕获最外层的标签对 并替换它。
因此,在上面给定的正则表达式中,捕获组 将为您提供以下信息;
- 开始标记(完整)
[black]
- 开始标签(标签名称)
black
- 开始和结束标签之间的内容
My [black]house is [blue]very[/blue] beautiful[/black] today
- 结束标记
[/blue]
所以,你可以用$2来判断你正在处理的tag,替换成
<tag></tag>
// or even
<></>
哪个会给你;
// in first iteration
<tag>My [black]house is [blue]very[/blue] beautiful[/black] today</tag>
// in second iteration
<tag>My <tag2>house is [blue]very[/blue] beautiful</tag2> today</tag>
// in third iteration
<tag>My <tag2>house is <tag3>very</tag3> beautiful</tag2> today</tag>
代码
$text = "[blue]My [black]house is [blue]very[/blue] beautiful[/black] today[/blue]";
function convert($input)
{
$control = $input;
while (true) {
$input = preg_replace('~(\[(.*?)\])(.*)(\[/\])~s', '<></>', $input);
if ($control == $input) {
break;
}
$control = $input;
}
return $input;
}
echo convert($text);
正如其他人所说,不要试图重新发明轮子。
但是,您可以使用 递归 方法:
<?php
$text = "[blue]My [black]house is [blue]very[/blue] beautiful[/black] today[/blue]";
$regex = '~(\[ ( (?>[^\[\]]+) | (?R) )* \])~x';
$replacements = array( "blue" => "<bleu>",
"black" => "<noir>",
"/blue" => "</bleu>",
"/black" => "</noir>");
$text = preg_replace_callback($regex,
function($match) use ($replacements) {
return $replacements[$match[2]];
},
$text);
echo $text;
# <bleu>My <noir>house is <bleu>very</bleu> beautiful</noir> today</bleu>
?>
在这里,每个颜色标签都被其对应的法语(刚刚编造的)颜色标签所取代,请参阅有关该主题的 a demo on ideone.com. To learn more about recursive patterns, have a look at the PHP documentation。
所以我正在尝试制作一个 php 函数来从 BBCode-style 表单中获取 HTML 标签。事实上,我可以使用 preg_replace 轻松获得标签。但是当我在同一个 bbcode 中有一个 bbcode 时,我遇到了一些麻烦...
像这样:
[blue]My [black]house is [blue]very[/blue] beautiful[/black] today[/blue]
所以,当我 "parse" 它时,我总是保留蓝色的 bbcode。像 :
My house is [blue]very[/blue] beautiful today
除了第一个蓝色标签内的黑色标签内的蓝色标签外,所有内容都是彩色的。
我该怎么做?
有了更多信息,我试过了:
Regex: "/\[blue\](.*)\[\/blue\]/si" or "/\[blue\](.*)\[\/blue\]/i"
Getting : "My house is [blue]very[/blue] beautiful today"
Regex : "/\[blue\](.*?)\[\/blue\]/si" or "/\[blue\](.*)\[\/blue\]/Ui"
Getting : "My house is [blue]very beautiful today[/blue]"
我必须循环 preg_replace 吗? regex-style 没有循环的方法吗?
感谢您的关心。 :)
不应该在产品上重新发明轮子,而是选择 well-tested 插件是正确的。但是,如果您正在试验或从事宠物项目,请务必继续试验,享受乐趣并在过程中获得重要知识。
话虽如此,您可以尝试使用正则表达式。我会在下面为你分解。
(\[(.*?)\])(.*?)(\[/\])
哲学
在像这样解析标记时,您实际寻求的是 将标签与其成对 .
进行匹配因此,您可以采取的一种干净的方法是 运行 一个循环,并且 每次都捕获最外层的标签对 并替换它。
因此,在上面给定的正则表达式中,捕获组 将为您提供以下信息;
- 开始标记(完整)
[black]
- 开始标签(标签名称)
black
- 开始和结束标签之间的内容
My [black]house is [blue]very[/blue] beautiful[/black] today
- 结束标记
[/blue]
所以,你可以用$2来判断你正在处理的tag,替换成
<tag></tag>
// or even
<></>
哪个会给你;
// in first iteration
<tag>My [black]house is [blue]very[/blue] beautiful[/black] today</tag>
// in second iteration
<tag>My <tag2>house is [blue]very[/blue] beautiful</tag2> today</tag>
// in third iteration
<tag>My <tag2>house is <tag3>very</tag3> beautiful</tag2> today</tag>
代码
$text = "[blue]My [black]house is [blue]very[/blue] beautiful[/black] today[/blue]";
function convert($input)
{
$control = $input;
while (true) {
$input = preg_replace('~(\[(.*?)\])(.*)(\[/\])~s', '<></>', $input);
if ($control == $input) {
break;
}
$control = $input;
}
return $input;
}
echo convert($text);
正如其他人所说,不要试图重新发明轮子。
但是,您可以使用 递归 方法:
<?php
$text = "[blue]My [black]house is [blue]very[/blue] beautiful[/black] today[/blue]";
$regex = '~(\[ ( (?>[^\[\]]+) | (?R) )* \])~x';
$replacements = array( "blue" => "<bleu>",
"black" => "<noir>",
"/blue" => "</bleu>",
"/black" => "</noir>");
$text = preg_replace_callback($regex,
function($match) use ($replacements) {
return $replacements[$match[2]];
},
$text);
echo $text;
# <bleu>My <noir>house is <bleu>very</bleu> beautiful</noir> today</bleu>
?>
在这里,每个颜色标签都被其对应的法语(刚刚编造的)颜色标签所取代,请参阅有关该主题的 a demo on ideone.com. To learn more about recursive patterns, have a look at the PHP documentation。