0

基本的に私がやろうとしているのは、正規表現を使用せずに一種の BB コード システムを作成することです。以下で使用しているコードは、そうではありませんが、完全に機能するようです。基本的に、コードは文字列を受け取り、すべての [code][/code] ブロック内からすべてのブレーク タグを削除し、それを文字列全体に置き換えることになっています。次に、コードは [code][/code] タグを、使用している SyntaxHighlighter スクリプトの「pre」タグに変換することになっています。

残念ながら、コードは 100% 完全に機能するわけではありません。場合によっては、[code][/code] ブロック内にブレーク タグが残ることがあります。私のコードは次のとおりです。

<?php
$string = "Hello\n[code]\nCode One\n[/code]\n[code]\nCode Two\n[/code]\n[code]\nCode    Three\n[/code]";
$string = nl2br($string);
$openArray = array();
$closeArray = array();
$original = "";
$newString = "";

$i = 0;
if(strpos($string, "[code]") === 0) {
    array_push($openArray, 0);
}
while($i = strpos($string, "[code]", $i + 1)) {
    array_push($openArray, $i);
}
while($i = strpos($string, "[/code]", $i + 1)) {
    array_push($closeArray, $i + 7);    
}
for($j = 0; $j < count($openArray); $j++) {
    $length = $closeArray[$j] - $openArray[$j];
    $original = substr($string, $openArray[$j], $length);
    $newString = strip_tags($original);
    $string = str_replace($original, $newString, $string);
}
$string = str_replace("[code]", '<pre class="brush: plain">', $string);
$string = str_replace("[/code]", '</pre>', $string);
echo $string;
?>

かなり長い間これの何が問題なのか疑問に思っていて、さまざまな方法を試してきたので、すべての回答は大歓迎です!

4

2 に答える 2

1

あなたの処理で私が目にする主な問題は、開始タグと終了タグを互いにかなり独立して保存することです。その後、それぞれが互いに属しているかのようにそれらを処理しますが、終了コードが開始コードに続くかどうかを検証せず、解析を提供する必要がある2つの開始コードまたは終了コードがない場合は検証しないため、それは保証されませんエラー。

strpos のように、開始コードと終了コードのペアの次の位置を返す小さなヘルパー関数を自分で作成できます。

function codepos($string, $code, $offset) {
    $offset = 0;
    if (FALSE === $start = strpos($string, "[$code]", $offset)) {
        return FALSE;
    }
    if (FALSE === $stop = strpos($string, "[/$code]", $start) {
        throw new Exception('Close code not found.');
    }
    if ($next = strpos($string, "[$code]", $start + 1) && $next < $stop) {
        throw new Exception('Double opening detected.');
    } 
    $pos = new stdClass;
    $pos->start = $start;
    $pos->stop = $stop;
    $pos->code = $code;
    return $pos;
}

物事が順調に進んでいることがすでにわかっているので、この変更を処理するのは簡単です。例外をスローする代わりに、単に FALSE を実行して、何らかの方法で通知することができます。また、このルーチンは、最初の開始コードの前にある終了コードをまだチェックしていません。

$offset = 0;
while($pos = codepos($string, 'code', $offset))
{
    ... process each code-pair.
}
于 2012-06-19T02:01:49.283 に答える
0

学習またはイントラネットツールの場合のみ、wwwでは考慮されません。考慮に

入れる必要があります。
行は文字列バッファより長い場合があります。あなたがそれの周りにコーディングしない限り、あなたが最大の行サイズを持っていることを知ってください。

入力が常に正しいと想定しない限り、オープンタグの前にクローズタグがあり、クローズ/オープンタグが欠落している可能性があることをコーディングします。

次の場合を処理できます
。State11つ以上のオープンタグを探しています:
オープン/クローズタグなし
オープンタグのみ
最初にクローズタグ-解析は
、1つ以上の一致するオープン/クローズタグ(適切な順序で)
1つ以上の一致するオープン/クローズタグ(適切な順序で)オープンタグで
終わるドキュメントの終わり
-OK State2クローズタグを探しています:
クローズタグとそれに続く1つ以上の一致するオープン/クローズタグ(適切な順序)
クローズタグとそれに続く1つ以上の一致するオープン/クローズタグ(適切な順序)オープンタグで終わる
クローズタグなし
ドキュメントの終わり-解析が失敗する

于 2012-06-19T02:14:39.807 に答える