0

PHP テンプレート エンジンを作成しようとしています。

次の文字列を検討してください。

@foreach($people as $person)
    <p></p>
$end

次の正規表現を使用して見つけることができます。

@[\w]*\(.*?\).*?@end

しかし、この文字列がある場合:

@cake()
    @cake()
        @fish()
        @end
    @end
@end

正規表現は失敗します。次のようになります。

@cake()
    @cake()
        @fish()
        @end

前もって感謝します。

4

2 に答える 2

2

ネストされた関数を照合できます。例:

$pattern = '~(@(?<func>\w++)\((?<param>[^)]*+)\)(?<content>(?>[^@]++|(?-4))*)@end)~';

または名前付きキャプチャなし:

$pattern = '~(@(\w++)\(([^)]*+)\)((?>[^@]++|(?-4))*)@end)~';

パターン全体を先読みすると、ネストされたすべての関数のすべてのコンテンツを取得できることに注意してください。(?=...)

パターンの詳細:

~                # pattern delimiter
(                # open the first capturing group
    @(\w++)      # function name in the second capturing group
    \(           # literal (
    ([^)]*+)     # param in the third capturing group
    \)           # literal )
    (            # open the fourth capturing group
    (?>          # open an atomic group
        [^@]++   # all characters but @ one or more times
      |          # OR
        (?-4)    # the first capturing group (the fourth on the left, from the current position)
    )*           # close the atomic group, repeat zero or more times
    )            # close the fourth capturing group 
    @end        
)~               # close the first capturing group, end delimiter
于 2013-08-03T06:28:20.117 に答える
0

You have nesting, which takes you out of the realm of a regular grammar, which means that you can't use regular expressions. Some regular expression engines (PHP's included, probably) have features that let you recognize some nested expressions, but that'll only take you so far. Look into traditional parsing tools, which should be able to handle your work load. This question goes into some of them.

于 2013-08-03T04:46:17.150 に答える