搜索和替换
有几种不同的函数/方法可以用其他东西替换字符串的某个部分,它们都有自己的优势。
##str_replace() 方法(二进制安全;区分大小写)
参数
混合str_replace(混合$search,混合$replace,混合$subject [, int &$count])
str_replace() 有 3 个必需的参数,正如您在上面的定义中看到的,它们的顺序正确,所有这些参数都可以将字符串作为数组作为参数!
搜索和替换
-
search(string) AND replace(string) → 用替换字符串替换搜索字符串。
-
search(array) AND replace(string) → 用替换字符串替换所有搜索元素。
-
search(string) AND replace(array) → 提示您:“Notice: Array to string conversion”,因为替换数组仅用于一个搜索字符串没有意义,所以它尝试将数组转换为字符串。
-
search(array) AND replace(array) → 用相应的替换元素替换每个搜索元素(忽略键!)。
-
search(more elements) AND replace(less elements) → 用相应的替换元素替换每个搜索元素(对于缺少的替换元素,将使用空字符串)。
-
search(less elements) AND replace(more elements) → 用对应的替换元素替换每个搜索元素(不需要的替换元素被忽略)。
主题
代码
echo str_replace("search", "replace", "text search text");
echo str_replace(["t", "a"], "X", "text search text");
echo str_replace("search", ["replace1", "replace2"], "text search text");
echo str_replace(["a", "c"], ["X", "Y"], "text search text");
输出
text replace text
XexX seXrch XexX
Notice: Array to string conversion
text seXrYh text
备注
- 明白了!
重要的是要知道str_replace() 从数组的左到右工作。这意味着它可以替换您已经替换的值。例如:
echo str_replace(array("a", "b"), array("b", "c"), "aabb");
//Probably expected output: bbcc
//Actual output: cccc
- 不区分大小写
如果您想让搜索不区分大小写,可以使用str_ireplace()(注意i 区分大小写-insensitive)。
- 多维数组
str_replace()/str_ireplace() 不适用于多维数组。有关此类实现,请参阅此 manual comment。当然你也可以把str_replace()换成str_ireplace()来区分大小写。
如果您想将所有内容放在一起并创建一个也适用于不区分大小写的多维数组的函数,您可以执行以下操作:
<?php
function str_ireplace_deep($search, $replace, $subject)
{
if (is_array($subject))
{
foreach($subject as &$oneSubject)
$oneSubject = str_ireplace_deep($search, $replace, $oneSubject);
unset($oneSubject);
return $subject;
} else {
return str_ireplace($search, $replace, $subject);
}
}
?>
##strtr() 方法(50% 二进制安全;区分大小写)
参数
字符串strtr(字符串$str,字符串$from,字符串$to)
字符串strtr(字符串$str,数组$replace_pairs)
该函数要么接受 3 个带有 from 和 to 字符串的参数,要么接受 2 个带有替换数组 array("search" => "replace" /* , ... */) 的参数,所有这些都可以在上面的定义中以正确的顺序看到。
2 个参数
它开始用对应的值替换最长的键,直到它替换了所有的key => value 对。在这种情况下,该函数是二进制安全的,因为它使用整个键/值。
3 个参数
它将主题中的 from 参数替换为 to 参数逐字节。所以它不是二进制安全的!
如果 from 和 to 参数的长度不等,则替换将在到达较短字符串的末尾时停止。
主题
它不接受一个数组作为主题,只接受一个字符串。
代码
echo strtr("text search text", "ax", "XY");;
echo strtr("text search text", ["search" => "replace"]);
输出
teYt seXrch teYt
text replace text
备注
- 明白了!
相对于str_replace(),strtr() 不会替换被替换的字符串。举个例子:
echo strtr("aabb", ["a" => "b", "b" => "c"]);
//If expecting to replace replacements: cccc
//Actual output: bbcc
另外,如果你想用相同的字符串替换多个东西,你可以使用array_fill_keys() 用值填充你的替换数组。
- 不区分大小写
strtr() 不区分大小写也不存在不区分大小写的等效函数。请参阅manual comment 了解不区分大小写的实现。
- 多维数组
strtr() 反对 str_replace() 不使用数组作为主题,因此它也不适用于多维数组。您当然可以将上面来自 str_replace() 的代码用于多维数组,并将其与 strtr() 或 stritr() 的实现一起使用。
如果您想将所有内容放在一起并创建一个也适用于不区分大小写的多维数组的函数,您可以执行以下操作:
<?php
if(!function_exists("stritr")){
function stritr($string, $one = NULL, $two = NULL){
/*
stritr - case insensitive version of strtr
Author: Alexander Peev
Posted in PHP.NET
*/
if( is_string( $one ) ){
$two = strval( $two );
$one = substr( $one, 0, min( strlen($one), strlen($two) ) );
$two = substr( $two, 0, min( strlen($one), strlen($two) ) );
$product = strtr( $string, ( strtoupper($one) . strtolower($one) ), ( $two . $two ) );
return $product;
}
else if( is_array( $one ) ){
$pos1 = 0;
$product = $string;
while( count( $one ) > 0 ){
$positions = array();
foreach( $one as $from => $to ){
if( ( $pos2 = stripos( $product, $from, $pos1 ) ) === FALSE ){
unset( $one[ $from ] );
}
else{
$positions[ $from ] = $pos2;
}
}
if( count( $one ) <= 0 )break;
$winner = min( $positions );
$key = array_search( $winner, $positions );
$product = ( substr( $product, 0, $winner ) . $one[$key] . substr( $product, ( $winner + strlen($key) ) ) );
$pos1 = ( $winner + strlen( $one[$key] ) );
}
return $product;
}
else{
return $string;
}
}/* endfunction stritr */
}/* endfunction exists stritr */
function stritr_deep($string, $one = NULL, $two = NULL){
if (is_array($string))
{
foreach($string as &$oneSubject)
$oneSubject = stritr($string, $one, $two);
unset($oneSubject);
return $string;
} else {
return stritr($string, $one, $two);
}
}
?>
##preg_replace() 方法(二进制安全;区分大小写)
参数
混合 preg_replace ( 混合 $pattern ,混合 $replacement ,混合 $subject [, int $limit = -1 [, int & $count ]])
preg_replace() 有 3 个必需参数,按上述顺序排列。现在它们三个都可以将字符串作为数组作为参数!
搜索和替换
-
search(string) AND replace(string) → 用替换字符串替换搜索正则表达式的所有匹配项。
-
search(array) AND replace(string) → 用替换字符串替换每个搜索正则表达式的所有匹配项。
-
search(string) AND replace(array) → 给你一个警告:“Warning: preg_replace(): Parameter mismatch, pattern is a string while replacement is an数组”,因为仅一个搜索正则表达式的替换数组没有意义。
-
search(array) AND replace(array) → 用相应的替换元素替换每个搜索正则表达式的所有匹配项(忽略键!)。
-
search(more elements) AND replace(less elements) → 用相应的替换元素替换每个搜索正则表达式的所有匹配项(对于缺少的替换元素,一个空字符串将被使用)。
-
搜索(更少元素)和替换(更多元素) → 将每个搜索正则表达式的所有匹配项替换为相应的替换元素(忽略不需要的替换元素)。
主题
再次请注意:搜索必须是正则表达式!这意味着它需要分隔符并且需要转义特殊字符。
代码
echo preg_replace("/search/", "replace", "text search text");
echo preg_replace(["/t/", "/a/"], "X", "text search text");
echo preg_replace("/search/", ["replace1", "replace2"], "text search text");
echo preg_replace(["a", "c"], ["X", "Y"], "text search text");
输出
text replace text
XexX seXrch XexX
Warning: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
text seXrYh text
备注
- 明白了!
与str_replace() 相同,preg_replace() 从数组的左到右工作。这意味着它可以替换您已经替换的值。例如:
echo preg_replace(["/a/", "/b/"], ["b", "c"], "aabb");
//Probably expected output: bbcc
//Actual output: cccc
- 不区分大小写
由于搜索参数是一个正则表达式,您可以简单地传递flag i 进行不区分大小写的搜索。
- 多维数组
preg_replace() 不适用于多维数组。
- 反向引用
请注意,您可以使用\\n/$n 作为正则表达式捕获组的反向引用。其中0 是整个比赛,1-99 是您的捕获组。
此外,如果反向引用后面紧跟一个数字,则必须使用 \${n}。
- 替换/“/e 修饰符已弃用”
preg_replace() 中的替换不能使用回调函数作为替换。所以你必须使用preg_replace_callback()。当您使用修饰符 e 并获得“已弃用:preg_replace():/e 修饰符已弃用,请改用 preg_replace_callback”时相同。见:Replace preg_replace() e modifier with preg_replace_callback
如果您想将所有内容放在一起并创建一个也适用于不区分大小写的多维数组的函数,您可以执行以下操作:
<?php
function preg_replace_deep($search, $replace, $subject)
{
if (is_array($subject))
{
foreach($subject as &$oneSubject)
$oneSubject = preg_replace_deep($search, $replace, $oneSubject);
unset($oneSubject);
return $subject;
} else {
return preg_replace($search, $replace, $subject);
}
}
?>
##Loops while / for / foreach 方法(非二进制安全;区分大小写)
当然,除了所有这些函数之外,您还可以使用一个简单的循环来遍历字符串并替换您拥有的每个 search => replace 对。
但是,当您使用二进制安全、不区分大小写和多维数组时,这比仅使用上述函数要复杂得多。所以这里就不举例子了。
受影响的字符串
现在上面显示的所有方法都对整个字符串进行替换。但有时您只想为字符串的某个部分替换某些内容。
为此,您可能想要/可以使用substr_replace()。或者另一种常见的方法是使用substr() 并仅在该特定子字符串上应用替换,然后将字符串放在一起。当然,您也可以修改您的正则表达式或做其他事情以不将替换应用于整个字符串。