PHP preg_replace_callback игнорировать идентификатор

Я использую следующий код для соответствия всем буквам, кроме i и d .

/{([abcefghj-z]+)}/ 

Как я могу изменить его так, чтобы i и d могли существовать, но не в этом порядке (id).

Примеры строк:

 /admin/users/{type}/{id}/edit 

В приведенном выше примере заменяется только {type}.

Пример 2:

 /admin/users/{type}/{id}/{supplied}/edit 

В приведенном выше примере оба типа {type} и {provided} будут совпадать.

Возможно ли использование регулярного выражения?

ОБНОВИТЬ

Код, который я использую в соответствии с нижеприведенным сообщением:

 $current = 'admin/users/{type}/{id}/changePassword'; $parameters = array('type' => 'administrators', 'id' => '1'); $path = preg_replace_callback('~\{(?!id\})[az]+\}~', function ($m) use ($parameters) { return $parameters[$m[1]]; }, $current); 

Вот вам решение: вам нужно использовать группу захвата (таким образом, я добавил круглые скобки в ([az]+) ), чтобы получить нужное значение, и я вижу, что вам нужно выполнить поиск в case- (таким образом, я добавил ~i ):

 $current = 'admin/users/{type}/{id}/changePassword'; $parameters = array('type' => 'administrators', 'id' => '1'); $path = preg_replace_callback('~\{(?!id\})([az]+)\}~i', function ($m) use ($parameters) { // ^ ^ ^ return $parameters[$m[1]]; }, $current); echo $path; 

См. Демонстрацию IDEONE

При захвате группы $m[1] будет удерживать «тип», и вы получите правильное значение из массива.

Используйте отрицательное утверждение.

 \{(?!id\})[az]+\} 
  • (?!id\}) утверждает предыдущий токен { за ним следует любое, но не id} .
  • Если да, то сопоставьте одно или несколько строчных букв, а затем } .

DEMO

Пример:

Это заменит все согласованные подстроки {foo} .

 preg_replace('~\{(?!id\})[az]+\}~', '{foo}', $str); 

DEMO