The code that john at mccarthy dot net posted is not necessary. If you want your results grouped by individual match simply use:
<?
preg_match_all($pattern, $string, $matches, PREG_SET_ORDER);
?>
E.g.
<?
preg_match_all('/([GH])([12])([!?])/', 'G1? H2!', $matches); // Default PREG_PATTERN_ORDER
// $matches = array(0 => array(0 => 'G1?', 1 => 'H2!'),
// 1 => array(0 => 'G', 1 => 'H'),
// 2 => array(0 => '1', 1 => '2'),
// 3 => array(0 => '?', 1 => '!'))
preg_match_all('/([GH])([12])([!?])/', 'G1? H2!', $matches, PREG_SET_ORDER);
// $matches = array(0 => array(0 => 'G1?', 1 => 'G', 2 => '1', 3 => '?'),
// 1 => array(0 => 'H2!', 1 => 'H', 2 => '2', 3 => '!'))
?>