2012-03-30 3 views
1

中括弧内のコードの一部を取得するために、ある種の正規表現が必要です。これに関する他の質問がありますが、私のものとは少し異なります。中括弧内のコードを正しく取り込む方法は?

このコードをサンプルと見なします。

public function my_method($my_input) { 
    if(true == false) { $me = "Forever alone. :("; } 
    if(true == true) { $me = "No longer alone. :}"; } 
    if(false == false) { $me = ":{ - This is so Wrong."; } 
} 

と "パブリック関数my_method($ my_input)" の部分を無視します。

if(true == false) { $me = "Forever alone. :("; } 
    if(true == true) { $me = "No longer alone. :}"; } 
    if(false == false) { $me = ":{ - This is so Wrong."; } 

"{"と "}"の文字列(およびコメントなど)の中で誤解を招くことなく、どうやって取得できますか?

正規表現に関する私の知識は非常に限られており、これを達成するのに苦労しています。 :/

+0

PHPコードを解析しますか? – alexn

+0

これは、正規表現でHTMLを解析できないのと同じ理由で動作しません。PHPもHTMLも標準言語ではありません。 – moodywoody

+0

私は編集を内部メソッドのみに制限するコードエディタを作成/開発しようとしています。 – Diabolic

答えて

3

引用符がバックスラッシュであっても、ほとんどの場合、正規表現を作成しました。ここにスクリプト例があります。私は正規表現の中でコメントを提供しましたが、私は正規表現自体を文字列区切り文字として使用しているので、正規表現内のすべての 'をバックスラッシュする必要があったことに注意してください。

正規表現は再帰的であるため、大括弧がネストされているレベルの深さに制限はありません。しかし、括弧内にはエラーはありません(つまり、一致する括弧はありません)。それは論理的です。

$str = 
' 

public function my_method($my_input) { 
    if(true == false) { $me = "Forever alone. :("; } 
    if(true == true) { $me = "No longer alone. :}"; } 
    if(true == true) { $me = \'No longer alone. :}\'; } 
    if(true == true) { $me = \'No longer \\\' alone. :}\'; } 
    if(false == false) { $me = ":{ - This is so Wrong."; } 
} 

public function my_method($my_input) { 
    if(true == false) { $me = "Forever happy. :("; } 
    if(true == true) { $me = "No longer happy. :}"; } 
    if(true == true) { $me = \'No longer happy. :}\'; } 
    if(true == true) { $me = \'No longer \\\' happy. :}\'; } 
    if(false == false) { $me = ":{ - This is so Wrong."; } 
} 

'; 

preg_match_all(
    '/ 
     {        # opening { 
     (       # matching parentheses 
      (?:      # non matching parentheses 
       (?:      # non matching parentheses 
        [^{}"\']+   # anything but { } " and \' 
        |     # or 
        "     # opening " 
        (?:    # non matching parentheses 
         [^"\\\]*  # anything but " and \ 
         |    # or 
         \\\"   # a \ followed by a " 
        )*    # as often as possible 
        "     # closing " 
        |     # or 
        \'     # opening \' 
        (?:    # non matching parentheses 
         [^\'\\\\]*  # anything but \' and \ 
         |    # or 
         \\\\\'   # a \ followed by a \' 
        )*    # as often as possible 
        \'     # closing \' 
       )*      # as often as possible 
       |      # or 
       (?R)     # repeat the whole pattern 
      )*       # as often as possible 
     )        # close matching parentheses 
     }        # closing } 
    /xs', 
    $str, 
    $matches 
); 

print_r($matches); 
+0

できるだけ早くこれをテストするつもりです。オハイオ州神、それがうまくいけば素晴らしい! – Diabolic

+0

奇跡的に働く!ありがとうございます。^^ – Diabolic

4

マッチするカッコは、正規表現で試してはいけないプロトタイプの例の1つです(文字列内にカッコがない場合でも正規表現にはあまりにも複雑です)。

これは、ネストされたかっこを持つ(正式な)言語は規則的ではありませんが、単純な正規表現よりもはるかに複雑な文脈自由文法で表されるためです。非常に高いレベルでは、正規表現は「任意の大きな数には数えられません」、つまり、どの閉じ括弧がどのかっこに属しているかを認識できません(PHPなどの任意の括弧の深さを許可する限り))。

文脈自由文法をサポートしているツールや、既に書かれているPHPパーサを入手する方がよいでしょう。

機能自分をを抽出するために、あなたはおそらくちょうどキーワードfunction(または機能ブロックを示す他のキーワード)を探してください、との括弧({)にアクセスしてください。次に、現在の文字列かコメントかどうかを確認しながら、一致する閉じ括弧(})が見つかるまで、文字単位で続けることができます。

しかし、私は可能なすべてのコーナーケースの世話をするのは非常に煩雑になる可能性が想像することができるので、自分の手でこのタスクを実行することができたくない...

+0

ありがとうございました。私はregexpにいくつかのポイントまで試してみましょう。私は同時にPHPパーサーも探しています。 – Diabolic

2

正規表現は右ではありませんこれについては@phimuemue's answerを参照してください。

あなたのスクリプトにはPHP's own tokenizerを使用できます。しかし、それは単にあなたに「何ブロック内にあるもの」を与えるのではなく、ブロック内のトークンを与えるだけです。あなたがしたいことに応じて、トークンからソースコードを再構築する必要があります。

+0

ありがとう、これは私のために有益に見えます。 – Diabolic

関連する問題