@nickb が既にコメントしたように、繰り返されるキャプチャ グループは最後の一致のみを保持します。私の知る限り、すべての一致を保持する実装を提供するのは.NETだけです。したがって、少なくとも 2 つの一致を使用する必要があるという @m.buettner に同意します。また、@ IngmardeLangeのソリューションは代替実装のようですが、チェックしていませんが、少なくとも2つの一致を使用しています.
楽しみのために、1 つのマッチを使用してこれを行う方法を考案しました。最初のアイデアは、@{article
部分に後読みを使用することでしたが、可変長の後読みはサポートされていません。次に、(残念ながら、あなたが目撃しようとしているように)@TimPietzckerが可変長の後読みを実装するためのトリックについて言及したことを思い出しました:逆の文字列で可変長の先読みを行います。(実際にこのメソッドを使用しないでください。)
<?php
function get_attr_val_matches($tag, $subject)
{
$regex = '/"(\w+)"=(\w+)\s+(?=(?:"\w+"=\w+\s+)*' . strrev($tag) . '\{@)/';
preg_match_all($regex, strrev($subject), $matches, PREG_SET_ORDER);
foreach ($matches as &$match)
{
$match = array_map(strrev, $match);
$match = array($match[0], array_reverse(array_slice($match, 1)));
}
return array_reverse($matches);
}
$tag = 'articles';
$subject = '@{articles mode="extrait" nb="3"}';
print_r(get_attr_val_matches($tag, $subject));
?>
出力:
Array
(
[0] => Array
(
[0] => mode="extrait"
[1] => Array
(
[0] => mode
[1] => extrait
)
)
[1] => Array
(
[0] => nb="3"
[1] => Array
(
[0] => nb
[1] => 3
)
)
)
実行例を次に示します。
明らかに、これについてまだ十分に断言していない場合、すべての逆転には、2 つのマッチを実行するよりも多くのコストがかかります。しかし、おそらく、可変長の後読みを持つ式を一般的に変換し、上記のように逆先読みに変換してから戻すアプリケーションがあります。おそらくそうではありませんが。