我需要使用PHP替换phpBB3论坛中的BBCode引号。引用的帖子如下所示:
[quote="John Doe":2sxn61wz][quote="Bob":2sxn61wz]Some text from Bob[/quote:2sxn61wz]Some text from John Doe[/quote:2sxn61wz]Some more text
我想解析这个字符串,最后得到一个像:
这样的数组Array (
[0] => Array (
[0] => 'John Doe'
[1] => 'Some text from John Doe'
)
[1] => Array (
[0] => 'Bob'
[1] => 'Some text from Bob'
)
)
递归查找这些引用块及其内容的最佳方法是什么?提前感谢您提供任何帮助!
正如评论中所述:
$str = '[quote="John Doe":2sxn61wz][quote="Bob":2sxn61wz]Some text from Bob[/quote:2sxn61wz]Some text from John Doe[/quote:2sxn61wz]Some more text';
$uid = '2sxn61wz';
print_r(quoteParser($str, $uid));
function quoteParser($str, $uid) {
$pattern = "#\[quote(?:="(.*?)")?:$uid\]((?!\[quote(?:=".*?")?:$uid\]).)?#ise";
echo "Unparsed string: " . $str . "<br /><br />";
echo "Pattern: " . $pattern . "<br /><br />";
preg_match_all($pattern, $str, $matches);
return $matches;
}
输出:
Array ( [0] => Array ( [0] => [quote="John Doe":2sxn61wz] [1] => [quote="Bob":2sxn61wz]S ) [1] => Array ( [0] => John Doe [1] => Bob ) [2] => Array ( [0] => [1] => S ) )
这完全是我需要的,但我没有得到引用的文字。只有用户名。有帮助吗?谢谢到目前为止。
答案 0 :(得分:2)
显然你想要的是将你的BBCode输出变成HTML。如果您愿意,可以查看bbcode_create()
功能。否则,不同的递归 - 格式化你的文本 - 是一个更好的选择,我相信。
<style type="text/css">
body {
font-size:.9em;
font-family:Arial, Helvetica, sans-serif;
}
.post {
margin:1em;
padding:1em;
font-size:1em;
border:1px solid #999;
}
.post > .text {margin:1em .4em}
.post > div:first-child {margin-top:0}
.post > div:last-child {margin-bottom:0}
.post > .quote {border-color:#CCC}
.quote {
margin:1em 2em;
background-color:#F9F9F9;
border:1px solid #AAA;
font-style:italic;
}
.quote .text {margin:.7em 1em}
.quote .author {
color:#039;
font-size:.8em;
background-color:#E0E0E0;
padding:.5em .8em;
margin:.5em;
}
.author a {
font-weight:bold;
text-decoration:none;
color:inherit;
}
.author a:hover {text-decoration:underline;}
</style>
function str2html($str,$className='post') {
$patPost =
'~(
\[quote="(?:(?!").)+":(\w+)(?:\])
(?:
(?(?=\[quote="(?:(?!").+)":\w+\])
(?R)
|
(?(?!\[/quote:\2\]).)
)*
)
\[/quote:\2\]
)~xis';
// note that these 2 are not identical
$patQuote =
'~
(\[quote="((?:(?!").)+)":(\w+)(?:\]))
(
(?(?=\[quote="(?:(?!").+)":\w+\])
(?R)
|
(?(?!\[/quote:\3\]).)
)*
)
(\[/quote:\3\])
~xis';
$arr = preg_split($patPost,$str,-1,PREG_SPLIT_DELIM_CAPTURE);
foreach ($arr as &$value) $value = trim($value);
unset($value);
//echo '<h2>split post</h2>'; print_r($arr);
$res = empty($className) ? '' : "<div class=\"{$className}\">";
for ($i = 0; $i < count($arr); $i += 3) {
if (!empty($arr[$i]))
$res .= '<div class="text">' . $arr[$i] . '</div>';
if (!empty($arr[$i+1]))
$res .= preg_replace_callback($patQuote,'replaceQuote',$arr[$i+1]);
}
$res .= empty($className) ? '' : '</div>';
return $res;
}
function replaceQuote($m) {
//echo '<h2>replacing quotes</h2>'; print_r($m);
$res = '<div class="quote">';
$res .= '<div class="author">';
$res .= '<a href="">' . $m[2] . '</a> wrote:';
$res .= '</div>';
$res .= str2html($m[4],'');
$res .= '</div>';
return $res;
}
您可以通过echo str2html('some string here')
拨打此电话。你明白了。
答案 1 :(得分:1)
这是一个递归版本。它匹配字符串中的所有引号。我就是这样做的。如果整个目的是在html中更好地显示每个代码,那么我将改为使用正确的Regex模式修改内容而不是匹配它们。
$str = '[quote="John Doe":2sxn61wz]' .
'[quote="Bob":2sxn61wz]' .
'Some text from Bob[/quote:2sxn61wz]' .
'Some text from John Doe[/quote:2sxn61wz]' .
'Some more text';
$str .= '[quote="MrUpsidown":2sxn61wz]Some other quote[/quote:2sxn61wz]';
//$str .= '[quote="MrUpsidown":2sxn61wz]Yet another one[/quote:2sxn61wz]';
$pat =
'~
\[quote="((?:(?!").)+)":(\w+)(?:\])
(
(?(?=\[quote="(?:(?!").+)":\w+\])
(?R)
|
(?(?!\[/quote:\2\]).)
)*
)
\[/quote:\2\]
~xis';
preg_match_all($pat,$str,$matches);
echo '<h2>Matches:</h2>'; print_r($matches);
$quotes = array();
function replaceQuote($m) {
global $curArr; global $pat;
$curArr[] = array(
'name' => $m[1],
'quote' => preg_replace_callback(
$pat,'replaceQuote',$m[3]
)
);
return preg_replace($pat,'',$m[0]);
}
if (!empty($matches[0])) {
foreach ($matches[0] as $k => $v) {
$quotes[] = array(
array(
'name' => $matches[1][$k],
'quote' => $matches[3][$k]
)
);
$curArr = &$quotes[count($quotes)-1];
$curArr[0]['quote'] = preg_replace_callback(
$pat,'replaceQuote',$curArr[0]['quote']
);
}
unset($curArr);
}
echo '<h2>Result:</h2>'; print_r($quotes);
这是输出。
匹配
Array ( [0] => Array ( [0] => [quote="John Doe":2sxn61wz][quote="Bob":2sxn61wz]Some text from Bob[/quote:2sxn61wz]Some text from John Doe[/quote:2sxn61wz] [1] => [quote="MrUpsidown":2sxn61wz]Some other quote[/quote:2sxn61wz] ) [1] => Array ( [0] => John Doe [1] => MrUpsidown ) [2] => Array ( [0] => 2sxn61wz [1] => 2sxn61wz ) [3] => Array ( [0] => [quote="Bob":2sxn61wz]Some text from Bob[/quote:2sxn61wz]Some text from John Doe [1] => Some other quote ) )
结果:
Array ( [0] => Array ( [0] => Array ( [name] => John Doe [quote] => Some text from John Doe ) [1] => Array ( [name] => Bob [quote] => Some text from Bob ) ) [1] => Array ( [0] => Array ( [name] => MrUpsidown [quote] => Some other quote ) ) )
答案 2 :(得分:0)
尝试这样的事情:
$str = '[quote="John Doe":2sxn61wz][quote="Bob":2sxn61wz]Some text from Bob[/quote:2sxn61wz]Some text from John Doe[/quote:2sxn61wz]Some more text';
$quotes=array();
$quotes[]=quoteParser($str,$quotes);
print_r($quotes);
function quoteParser($str,&$quotes) {
$pattern = "/\[quote(?:="(.*?)")?:.{8}?\](.*)\[\/quote:2sxn61wz\](.*)/ise";
echo "Unparsed string: " . $str . "<br /><br />";
echo "Pattern: " . $pattern . "<br /><br />";
preg_match_all($pattern, $str, $matches);
if(empty($matches[0][0]))
return false;
$var=quoteParser($matches[2][0],$quotes);
$quotes[]=array($matches[1][0],$var?$var:$matches[2][0]);
return $matches[3][0];
}
输出:
数组([0] =&gt;数组([0] =&gt; Bob [1] =&gt;来自Bob的一些文字)[1] =&gt;数组([0] =&gt; John Doe [1] =&gt;来自John Doe的一些文字)[2] =&gt;更多文字)