Вы можете уменьшить количество шагов для создания желаемой строки, посмотрев на проблему по-другому.Сначала сопоставьте то, что вам нужно, затем замените пробелы и тире на _
в конце:
function make_post_type($s) {
preg_match_all("~({[^{}]*}|\[[^][]*])|[\w\s]+~", $s, $m);
$s = '';
foreach($m[0] as $k => $v) {
$s .= $m[1][$k] ? substr($v, 1, -1) : strtolower($v);
}
return preg_replace('~[-\s]+~', '_', $s);
}
Я заключил {[^{}]*}|\[[^][]*]
в скобки, чтобы позже можно было проверить (bool) $m[1][$k]
, который сообщает, является ли текущее значение витерация существует в захваченных группах, возвращаемых $m[1]
, затем удаляет один начальный и конечный символ из строки.
См. живое демо здесь