我要做的是在字符串中找到问号并将其替换为&
,但第一个除外。到目前为止我的代码:
$str = 'www.domain.com?adult=2&airport=40-48?destination=recko';
echo preg_replace(array('/[?]/'), '&', $str );
输出:
www.domain.com&adult=2&airport=40-48&destination=recko
如何忽略?
的第一次出现?
答案 0 :(得分:4)
将字符串的开头与第一个?
匹配,并使用(*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
模式详情:
^
- 字符串的开头[^?]*
- 尽可能多的?
以外的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 );
^([^?]*[?])
部分从开头的字符串部分匹配第一个?
并放入第1组。在我们传递匹配对象($m
)的匿名方法中,我们可以在!empty($m[1])
的帮助下检查小组是否匹配("参加了比赛")。如果是,我们就把它放回去。如果没有,[?]
,第二个分支匹配,那么,我们将其替换。
答案 1 :(得分:1)
我们只是循环思考整个字符串找到第一个?并用&替换所有其他人。不需要使用慢速的正则表达式
<?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;
答案 2 :(得分:0)
不知道这是否是最干净的方式,但是会起作用并且很容易:
echo substr($str,0,1) . preg_replace(array('/[?]/'), '&', substr($str,1));
答案 3 :(得分:0)
最好的方法是我认为是explode("?",$str)
或explode("&",$str)
并将它们放在一个数组中并使用小的if条件preg_replace()
进行第一次?
你要忽略并做array_marge()
。
尝试并让我知道
答案 4 :(得分:0)
请参阅parse_url
上的文档通过这种方式,您可以轻松提取部分网址,并仅在您感兴趣的组件上进行字符串替换
<?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'];
答案 5 :(得分:0)
您可以将lookbehind与\K
$str = preg_replace('/(?<=\?)[^?]*\K\?/', "&", $str);
lookbehind用于在匹配之前需要?
。 [^?]
匹配任何不是?
(negated character class)的字符。 \K
重置报告的匹配开头。
Demo at regex101或PHP demo at eval.in
或者使用capturing group代替\K
:(?<=\?)([^?]*)\?
and replace with $1&