2

PHP では、ネストされた角かっこを持つ文字列があります。

bar[foo[test[abc][def]]bar]foo

最初に内側のブラケット ペアに一致する正規表現が必要なのでpreg_match_all、一致するブラケット ペアを見つける順序は次のようになります。

[abc]
[def]
[test[abc][def]]
[foo[test[abc][def]]bar]

すべてのテキストは異なる場合があります。

これは可能preg_match_allですか?

4

2 に答える 2

2

これは正規表現では不可能です。正規表現がどれほど複雑であっても、常に一番左の一致が最初に返されます。

せいぜい、複数の正規表現を使用する必要がありますが、それでも、正規表現は一致するブラケットを実際にカウントできないため、問題が発生します。最善の策は、この文字列を別の方法で解析することです。

于 2013-02-21T14:53:02.653 に答える
0

あなたの質問では、どのような「一致の構造」が必要かは明らかではありません...しかし、使用できるのは単純な配列のみです。試す

  preg_match_all('#\[([a-z\)\(]+?)\]#',$original,$m); 

つまり、 for$original = 'bar[foo[test[abc][def]]bar]foo'は、内側の "abc" と "def" を含む配列を返します。


出力には、「解析タスク」のループが必要です。preg_replace_callbackを使用した PCREは、解析に適しています。

おそらく、このループは問題の良い手がかりです。

 $original = 'bar[foo[test[abc][def]]bar]foo';

 for( $aux=$oldAux=$original; 
      $oldAux!=($aux=printInnerBracket($aux)); 
      $oldAux=$aux
 );
 print "\n-- $aux";

 function printInnerBracket($s) {
    return preg_replace_callback(
            '#\[([a-z\)\(]+?)\]#',  // the only one regular expression
            function($m) {
               print "\n$m[0]"; 
               return "($m[1])";
            },
            $s
    );
 }

結果 (コールバック出力):

[abc]
[def]
[test(abc)(def)]
[foo(test(abc)(def))bar]
-- bar(foo(test(abc)(def))bar)foo

この関連する質問も参照してください。

于 2013-03-23T16:30:28.347 に答える