0

私はこのコードを持っています:

var s_1 = 'blabla [size=42]the answer[/size] bla bla blupblub';
var s_2 = 'blabla [size=42]the answer[/size] bla bla blupblub [size=32] 32 [/size]';

alert('Test-String:\n' + s_1 + '\n\nReplaced:\n' + size(s_1));
alert('Test-String:\n' + s_2 + '\n\nReplaced:\n' + size(s_2));


function size(s) {
    var reg = /\[size=(\d{1,2})\]([\u0000-\uFFFF]+)\[\/size\]/gi;
    s = s.replace(reg, function(match, p1, p2) {
        return '<span style="font-size: ' + ((parseInt(p1) > 48) ? '48' : p1) + 'px;">' + p2 + '</span>';
    })
    return s;    
}

「[size=nn][/size]」タグのすべての出現を置き換えることになっていますが、外側のタグのみを置き換えます。それらをすべて置き換える方法がわかりません。(PHP スクリプトの使用はお勧めしません。BB コード形式のテキストのライブ プレビューが必要です)

試して

4

4 に答える 4

4

一致する (ネストされている可能性がある) BBCode タグ

要素がネストされている場合は、マルチパス アプローチが必要です。これは、次の 2 つの方法のいずれかで実行できます。内側からのマッチング (再帰式は不要) または外側からのマッチング (再帰式が必要)。(同様の質問に対する私の回答も参照してください: PHP、 preg_replace のネストされたテンプレート) ただし、Javascript 正規表現エンジンは再帰式をサポートしていないため、正規表現を使用してこれを (正しく) 実行する唯一の方法は、裏返しにすることです。以下は、BBCode SIZE タグを内側から SPAN HTML タグに置き換えるテスト済みの関数です。以下の (高速) 正規表現は複雑であることに注意してください (1 つのこととして、Jeffrey Friedl の「ループ展開」効率化手法を実装しています - 参照: Mastering Regular Expressions (3rd Edition)詳細)、および IMO すべての複雑な正規表現は、読みやすいように完全にコメントしてフォーマットする必要があります。Javascript にはフリースペース モードがないため、以下の正規表現は最初に PHP フリースペース モードで完全にコメント化されて表示されます。実際に使用されるコメントなしの js 正規表現は、冗長なコメント付きのものと同じです。

(ネストされている可能性がある) SIZE タグの最も内側に一致する正規表現:

// Regular expression in commented (PHP string) format.
$re = '% # Match innermost [size=ddd]...[/size] structure.
    \[size=            # Literal start tag name, =.
    (\d+)\]            # $1: Size number, ending-"]".
    (                  # $2: Element contents.
      # Use Friedls "Unrolling-the-Loop" technique:
      #   Begin: {normal* (special normal*)*} construct.
      [^[]*            # {normal*} Zero or more non-"[".
      (?:              # Begin {(special normal*)*}.
        \[             # {special} Tag open literal char,
        (?!            # but only if NOT start of
          size=\d+\]   # [size=ddd] open tag
        | \/size\]     # or [/size] close tag.
        )              # End negative lookahead.
        [^[]*          # More {normal*}.
      )*               # Finish {(special normal*)*}.
    )                  # $2: Element contents.
    \[\/size\]         # Literal end tag.
    %ix';

Javascript 関数:parseSizeBBCode(text)

function parseSizeBBCode(text) {
    // Here is the same regular expression in javascript syntax:
    var re = /\[size=(\d+)\]([^[]*(?:\[(?!size=\d+\]|\/size\])[^[]*)*)\[\/size\]/ig;
    while(text.search(re) !== -1) {
        text = text.replace(re, '<span style="font-size: $1pt">$2</span>');
    }
    return text;
}

入力例:

r'''
[size=10] size 10 stuff
    [size=20] size 20 stuff
        [size=30] size 30 stuff [/size]
    [/size]
[/size]
'''

出力例:

r'''
<span style="font-size: 10pt"> size 10 stuff
    <span style="font-size: 20pt"> size 20 stuff
        <span style="font-size: 30pt"> size 30 stuff </span>
    </span>
</span>
'''

免責事項 - このソリューションは使用しないでください。

正規表現を使用して BBCode を解析することには危険が伴うことに注意してください! (ここで言及されていない「落とし穴」がたくさんあります。) 多くの人は、それは不可能だと言うでしょう。しかし、私は強く反対し、実際、再帰的な正規表現を使用し、非常にうまく機能する (そして高速な) 完全な BBCode パーサー (PHP で) を作成しました。ここで動作を確認できます: New 2011 FluxBB Parser (気弱な人向けではない非常に複雑な正規表現を使用していることに注意してください)。

しかし、一般的には、正規表現を非常に深く完全に理解している場合を除き、正規表現を使用して BBCode を解析しないように強く警告します (これは、Friedl の傑作を注意深く研究し、実践することで得られます)。つまり、あなたが正規表現の達人 (つまり、正規表現の第一人者) でない場合は、最も些細なアプリケーション以外で正規表現を使用しないようにしてください。

于 2012-10-17T16:33:57.667 に答える
2
var reg = /\[size=(\d{1,2})\]([\u0000-\uFFFF]+?)\[\/size\]/gi;
                                              ↑
                                    make it lazy (non-greedy)

と同じです

var reg = /\[size=(\d{1,2})\](.+?)\[\/size\]/gi;
于 2012-10-17T14:35:09.937 に答える
1

?の後に、で修飾された貪欲でない式を使用する必要があります+

デモ

于 2012-10-17T14:33:52.883 に答える
1

私は([\u0000-\uFFFF]+?) (untested)[/size]を使用しようとします。これは、最後のものに直接行くのではなく、最初の出現で停止するように指示します

編集

うん、テスト済み、問題ないようだ

于 2012-10-17T14:33:27.020 に答える