Возвращенный массив совпадений содержит в качестве первого элемента всю найденную строку, за которой следуют захваченные группы.
Я не могу найти опцию на php.net, чтобы просто вернуть захваченные группы?
Есть ли один?
Нет, для 0 стандартно содержится вся совпадающая строка.
0
Если бы это было проблемой, вы всегда могли бы unset($matches[0]) (что не повлияет на ключи) или array_slice($matches, 1).
unset($matches[0])
array_slice($matches, 1)