What I am trying to do is find question marks in a string and replace it with &
except the first one. My code so far:
$str = 'www.domain.com?adult=2&airport=40-48?destination=recko';
echo preg_replace(array('/[?]/'), '&', $str );
output:
www.domain.com&adult=2&airport=40-48&destination=recko
How can I ignore the first occurence of the ?
?
Match the start of the string up to the first ?
and use a (*SKIP)(*F)
to omit the first match:
$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
See the IDEONE demo
Pattern details :
^
- start of a string [^?]*
- 0+ characters other than ?
as many as possible \\?
- a literal ?
(*SKIP)(*F)
- two PCRE verbs making the regex engine omit the text matched so far in the current iteration |
- or [?]
- a literal ?
Alternative to (*SKIP)(*FAIL)
is to use preg_replace_callback
and the former pattern with the first alternative branch inside capturing parentheses :
$str = 'www.domain.com?adult=2&airport=40-48?destination=recko';
echo preg_replace_callback('/^([^?]*[?])|[?]/', function($m) {
return !empty($m[1]) ? $m[1] : "&";
}, $str );
See this IDEONE demo
The ^([^?]*[?])
part matches the string part from the start will the first ?
and places into Group 1. Inside the anonymous method where we pass the match object ( $m
), we can check if the group matched ("participated in the match") with the help of !empty($m[1])
. If it is, we just put it back. If not, the [?]
, the second branch matched, so, we replace it.
We just loop thought the whole string to find the first ? and replace every other with &. No need to use regex which is slow
<?php
$str = 'www.domain.com?adult=2&airport=40-48?destination=recko';
$strlen = strlen($str);
$passed_first = false;
for($i = 0; $i < $strlen; $i++) {
if($str[$i] == "?") {
if(!$passed_first) {
$passed_first = true;
} else {
$str[$i] = "&";
}
}
}
echo $str;
不知道这是否是最干净的方法,但是可以工作并且很容易:
echo substr($str,0,1) . preg_replace(array('/[?]/'), '&', substr($str,1));
The best way would be I think is do explode("?",$str)
or explode("&",$str)
and put them in a Array and do preg_replace()
with small if condition where you take the first ?
and rest you ignore and do array_marge()
.
try it and let me know
See documentation on parse_url
With this you can easily extract parts of the url and do string replace only on a component that interests you
<?php
$str = 'www.domain.com?adult=2&airport=40-48?destination=recko';
$url = parse_url($str);
$url['query'] = str_replace('?', '&', $url['query']);
echo $url['path'] . '?' . $url['query'];
You can use a lookbehind together with \\K
$str = preg_replace('/(?<=\?)[^?]*\K\?/', "&", $str);
The lookbehind is used to require a ?
before the one to be matched. [^?]
matches any character, that is not a ?
( negated character class ). \\K
resets beginning of the reported match.
Demo at regex101 or PHP demo at eval.in
Or by using a capturing group instead of \\K
: (?<=\\?)([^?]*)\\?
and replace with $1&
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.