如何替换字符串中除第一个字符之外的字符的出现
How to replace occurence of a character in a string except the first one
我想做的是在字符串中找到问号并将其替换为 &
除了第一个。到目前为止我的代码:
$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
如何忽略第一次出现的 ?
?
将字符串的开头匹配到第一个 ?
并使用 (*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
图案详情:
^
- 字符串的开头
[^?]*
- 除了?
之外的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])
的帮助下检查组是否匹配 ("participated in the match")。如果是,我们就把它放回去。如果不匹配,[?]
,第二个分支匹配,所以,我们替换它。
不知道这是否是最干净的方法,但可以工作并且很简单:
echo substr($str,0,1) . preg_replace(array('/[?]/'), '&', substr($str,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;
我认为最好的方法是做 explode("?",$str)
或 explode("&",$str)
并将它们放入一个数组中,然后用小的 if 条件做 preg_replace()
你取第一个 ?
剩下的你忽略并做 array_marge()
.
试试看然后告诉我
请参阅有关 parse_url
的文档
有了它,您可以轻松地提取部分 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'];
您可以使用 lookbehind together with \K
$str = preg_replace('/(?<=\?)[^?]*\K\?/', "&", $str);
lookbehind 用于在要匹配的那个之前要求 ?
。 [^?]
匹配任何不是 ?
(negated character class) 的字符。 \K
重置报告匹配的开头。
Demo at regex101 or PHP demo at eval.in
或者使用 capturing group instead of \K
: (?<=\?)([^?]*)\?
and replace with &
我想做的是在字符串中找到问号并将其替换为 &
除了第一个。到目前为止我的代码:
$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
如何忽略第一次出现的 ?
?
将字符串的开头匹配到第一个 ?
并使用 (*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
图案详情:
^
- 字符串的开头[^?]*
- 除了?
之外的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])
的帮助下检查组是否匹配 ("participated in the match")。如果是,我们就把它放回去。如果不匹配,[?]
,第二个分支匹配,所以,我们替换它。
不知道这是否是最干净的方法,但可以工作并且很简单:
echo substr($str,0,1) . preg_replace(array('/[?]/'), '&', substr($str,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;
我认为最好的方法是做 explode("?",$str)
或 explode("&",$str)
并将它们放入一个数组中,然后用小的 if 条件做 preg_replace()
你取第一个 ?
剩下的你忽略并做 array_marge()
.
试试看然后告诉我
请参阅有关 parse_url
的文档有了它,您可以轻松地提取部分 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'];
您可以使用 lookbehind together with \K
$str = preg_replace('/(?<=\?)[^?]*\K\?/', "&", $str);
lookbehind 用于在要匹配的那个之前要求 ?
。 [^?]
匹配任何不是 ?
(negated character class) 的字符。 \K
重置报告匹配的开头。
Demo at regex101 or PHP demo at eval.in
或者使用 capturing group instead of \K
: (?<=\?)([^?]*)\?
and replace with &