Match начала строки до первой ?
и использовать (*SKIP)(*F)
пропустить первый матч:
$str = 'www.domain.com?adult=2&airport=40-48?destination=recko';
echo preg_replace('/^[^?]*\?(*SKIP)(*F)|[?]/', '&', $str);
// => www.domain.com?adult=2&airport=40-48&destination=recko
См детализирует IDEONE demo
Pattern:
^
- начало строки
[^?]*
- кроме 0+ символов ?
как можно больше
\?
- буквальный ?
(*SKIP)(*F)
- два PCRE глаголов делает движок регулярных выражений опустить текст, совпадающий до сих пор в текущей итерации
|
- или
[?]
- буквальный ?
Альтернативы (*SKIP)(*FAIL)
является использование preg_replace_callback
и бывший шаблон с первой альтернативной ветвью внутри сохраняющих круглых скобок:
$str = 'www.domain.com?adult=2&airport=40-48?destination=recko';
echo preg_replace_callback('/^([^?]*[?])|[?]/', function($m) {
return !empty($m[1]) ? $m[1] : "&";
}, $str);
См this IDEONE demo
^([^?]*[?])
часть соответствует части строки с самого начала будет первыми ?
и помещается в группу 1. Внутри анонимного метода, где мы передаем объект соответствия ($m
), мы можем проверить, соответствует ли группа («участвовала в матче») с помощью !empty($m[1])
. Если да, мы просто вернем его обратно. Если нет, то [?]
, вторая ветка соответствует, поэтому мы ее заменим.
Именно то, что я искал. Спасибо – Roman
очень хорошее объяснение – Roman
Если вы хотите, вы можете прочитать больше на ['* (SKIP) (* FAIL)' здесь] (http://stackoverflow.com/questions/24534782/how-do-skip-or- е-работа-на-регулярное выражение) –