Если вы не хотите сопоставлять этот шаблон без ,6
после этого, вы можете использовать:
^{map:\h+geo="(?P<lat>-?\d+(?:\.\d+)?)(?:,\d+)?,(?P<lon>-?\d+(?:\.\d+)?)(?:,\d+)?"[^}]+}
Объяснение
^{map:\h+geo=
Начало строки, совпадение {map:
и 1+ горизонтальных пробелов и geo="
(?P<lat>
Именованная группа захвата lat
-?\d+
Соответствие необязательно -, 1+ цифр
(?:\.\d+)?
Дополнительная часть для .
и цифр 1+
)
Закрыть группу
(?:,\d+)?
Дополнительная часть для ,
и цифр 1+
,
Запятая между значениями
(?P<lon>
Именованная группа захвата lon
-?\d+
Соответствие необязательно -, 1+ цифр
(?:\.\d+)?
Дополнительная часть для .
и цифр 1+
)
Закрыть группу
(?:,\d+)?
Дополнительная часть для ,
и цифр 1+
"[^}]+}
Match "и затем до закрытия }
Regex demo | Php demo
Например
$re = '/^{map:\h+geo="(?P<lat>-?\d+(?:\.\d+)?)(?:,\d+)?,(?P<lon>-?\d+(?:\.\d+)?)(?:,\d+)?"[^}]+}/';
$str = '{map: geo="20.471884,-157.505,6" p="Hawaii"}';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
$lat = $matches[0]["lat"];
$lon = $matches[0]["lon"];
echo $lat; // 20.471884
echo PHP_EOL;
echo $lon; // -157.505
Вы можете немного укоротить шаблон, вернув первый подшаблон с помощью (?1)
^{map:\h+geo="(?P<lat>-?\d+(?:\.\d+)?)(?:,\d+)?,(?P<lon>(?1))(?:,\d+)?"[^}]+}