2012-03-09 6 views
2

投稿された無数の質問から、ネストされたステートメントを置き換えるためにregexを使用することは可能ではないことがわかっています。一意のネストされたステートメントを正規表現または代替のものに置き換える

それは文がユニークである場合には何の違いを行う場合、私は思ったんだけど:

[if @test]TEST[if @second]SECOND[/if][/if] 

エンドブロックもユニークであるとき、私は不器用な回避策です知っている、それがうまく得ている:

[if @test]TEST[if @second]SECOND[/if @second][/if @test] 
$pattern = '%\[if @'.$dynamic.'.*?\](.*?)\[/if @'.$dynamic.'\]%s'; //Works with above 

エンドブロックを一意にすることなくregexを使用することはできますか?これを達成する正規表現の代替手段がありますか?

[if @test] TEST [if @second] SECOND [/ if] [/ if]のような任意のネストレベルを解析したいと思います。正規表現が実用的でない場合、誰でもPHPで実行可能な代替案を提案できますか?

+1

それはあなたが達成しようとしているされて何を:あなたは正規表現を求めたので

は、ここ1は、このようなネストされたif Sを一致させるのですか?希望の出力をサンプル入力してください。 – Madbreaks

+0

私は質問を編集しますが、目的はユニークなエンドブロックを必要とせずにregexを使って置換を行うことです。 – jsuissa

+1

問題は実際には*ネスト*ではなく、*任意の*ネストであります。たとえば、大括弧がちょうど4つの深さにネストされていることが分かっているなら、 'a [b [c [d [e] f] g] h] iのさまざまな部分を解析するための正規表現を簡単に書くことができます。大括弧の中には、その中にちょうどネストされた1つのセットがあります。同じ正規表現が 'a [b [c] d [e [f [g] h [i [j [k]] [n] o] p] q] r] s [ t] u] v] w'の場合、真の正規表現ではできません.POSはこれを可能にする拡張の種類をサポートしていません。 – ruakh

答えて

4

適切な解決策では、トークン化は、タグ、コメント、テキストなどの基本コンポーネントに文字列を含める必要があります。このステップは正規表現で行うことができ、のフラットリストのトークンを生成します。次に、構造と詳細が必要な構文木を構築するトークンを通って行く。 (両方のステップを組み合わせて1回のパスで実行することもできます)

このようにすべてが制御され、コードの一部を再解析する必要はありません。

一方、これは正規表現で行うことができますが、より制限されており、追加された深さごとにコードのネストされた部分を再解析する必要があります。

~ 
\[if\ @(\w++)] 
(
    (?> 
     (?: (?!\[if\ @\w++]|\[/if]) .)++ 
     | 
     (?R) 
    )*+ 
) 
\[/if] 
~xs 
+0

これは最も外側のIF要素と一致するものです。 +1 – ridgerunner

関連する問題