2

私は正規表現と、この場合、正規表現で実行できる再帰についてもっと理解しようとしています。

のネストされたブロックを一致させようとしてい{foreach $VAR} ... {/foreach}ます。しかし、何らかの理由で正規表現が一致せず、その理由がわかりません。

ここの誰かがそれに光を当てることができることを望んでいました。迅速な正規表現の修正には興味がありません。しかし、実際には、正規表現が期待どおりに機能しない理由としてもっと多くのことがあります。正確には何が起こっているのですか?

これは私が持っているコードです:

<?php
$str = 'start of text
{foreach $ABC}
  in 1st loop
  {foreach $XYZ}
    in 2nd loop
  {/foreach}
{/foreach}
some other stuff';

if ( preg_match ( '#{foreach \$.*?}((?!foreach)|(?R))*{/foreach}#', $str, $matches ) )
{
    print_r($matches);
}
else
{
    echo 'No match';
}

これが私の正規表現の内訳です。

{foreach \$     #match literally "{foreach $"
.*?}            #followed by any character ending with a '}'
(               # start a group
  (?!foreach)   # match any character, aslong as it's not the sequence 'foreach'
  |             # otherwise
  (?R)          # do a recursion
)               # end of group
*               # match 0 or more times with a backtrace...
{/foreach}      # ...backtracing until you find the last {/foreach}

それが正規表現の仕組みだと思います。しかし、明らかにそうではありません。だから私の質問は、私の説明のどこが間違っているのですか?

ここでこのコードをいじることができます: http://codepad.viper-7.com/508V9w


明確にするために。

foreach各ブロックの内容を取得しようとしています。だから私の場合:

arr[0] => in 1st loop
      {foreach $XYZ}
        in 2nd loop
      {/foreach}
arr[1] => in 2nd loop

また -

arr[0] => {foreach $ABC}
      in 1st loop
      {foreach $XYZ}
        in 2nd loop
      {/foreach}
    {/foreach}
arr[1] => {foreach $XYZ}
        in 2nd loop
      {/foreach}

どちらでもうまくいきます。

4

1 に答える 1

0

まず第一に、はデフォルトで改行以外.のものと一致します。改行にも一致させるには、修飾子を設定する必要があります。s

次に、ここでアサーションを使用しています:((?!foreach)|(?R))*が、一致する実際の文字はありません。*数量詞などの前に少なくともドットが必要です。

#{foreach \$.*?}((?!foreach)|(?R)).*{/foreach}#sテストテキストで次の結果が得られます。

Array
(
    [0] => {foreach $ABC}
  in 1st loop
  {foreach $XYZ}
    in 2nd loop
  {/foreach}
{/foreach}
    [1] => 
)
于 2013-03-18T14:49:00.707 に答える