1

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 ) ) 

それは私が必要としているものですが、引用されたテキストを取得できません。ユーザー名のみ。何か助けはありますか?これまでありがとう。

4

3 に答える 3

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=&quot;(?:(?!&quot;).)+&quot;:(\w+)(?:\])
            (?:
                (?(?=\[quote=&quot;(?:(?!&quot;).+)&quot;:\w+\])
                    (?R)
                    |
                    (?(?!\[/quote:\2\]).)
                )*
            )
        \[/quote:\2\]
    )~xis';
    // note that these 2 are not identical
    $patQuote =
    '~
        (\[quote=&quot;((?:(?!&quot;).)+)&quot;:(\w+)(?:\]))
            (
                (?(?=\[quote=&quot;(?:(?!&quot;).+)&quot;:\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')。あなたはアイデアを得る。

于 2013-01-18T03:21:11.357 に答える
1

ここに再帰的なバージョンがあります。文字列内のすべての引用符に一致します。これは私がそれを行う方法です。全体の目的が各コードを html でより適切に表示することである場合、これらを一致させる代わりに、適切な正規表現パターンでコンテンツを変更します。

$str =  '[quote=&quot;John Doe&quot;:2sxn61wz]' .
        '[quote=&quot;Bob&quot;:2sxn61wz]' .
        'Some text from Bob[/quote:2sxn61wz]' .
        'Some text from John Doe[/quote:2sxn61wz]' . 
        'Some more text';
$str .= '[quote=&quot;MrUpsidown&quot;:2sxn61wz]Some other quote[/quote:2sxn61wz]';
//$str .= '[quote=&quot;MrUpsidown&quot;:2sxn61wz]Yet another one[/quote:2sxn61wz]';

$pat =
'~
    \[quote=&quot;((?:(?!&quot;).)+)&quot;:(\w+)(?:\])
        (
            (?(?=\[quote=&quot;(?:(?!&quot;).+)&quot;:\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
                    )

            )

    )
于 2013-01-16T17:27:47.257 に答える
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(?:=&quot;(.*?)&quot;)?:.{8}?\](.*)\[\/quote:2sxn61wz\](.*)/ise";

    echo "Unparsed string: " . $str . "&lt;br /&gt;&lt;br /&gt;";
        echo "Pattern: " . $pattern . "&lt;br /&gt;&lt;br /&gt;";
    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] => 配列 ( [0] => Bob [1] => Bob からのテキスト) [1] => 配列 ( [0] => John Doe [1] => John Doe からのテキスト) [2] => もう少しテキスト )

于 2013-01-16T15:42:27.307 に答える