Группирует одно совпадение, поскольку регулярное выражение X((a),?)*X
соответствует всей строке. Последние ((a),?)
будут сгруппированы.
То, что вы хотите сопоставить, это a
с X
перед ним (и началом строки), с запятой перед ним или с X
перед ним (и концом строки).
$target = 'Xa,a,aX';
$pattern = '/(?<=^X)a|a(?=X$|,)/';
preg_match_all($pattern, $target, $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
Выход:
Array
(
[0] => Array
(
[0] => Array
(
[0] => a
[1] => 1
)
[1] => Array
(
[0] => a
[1] => 3
)
[2] => Array
(
[0] => a
[1] => 5
)
)
)