str_replace
用替换替换所有出现的单词。
preg_replace
用替换替换模式的出现,并采用可选的限制参数。
我不需要模式匹配,但想要限制参数的便利性。我该怎么用?
答案 0 :(得分:9)
这是一个更好的方法
<?
$str = 'abcdef abcdef abcdef';
// pattern, replacement, string, limit
echo preg_replace('/abc/', '123', $str, 1); // outputs '123def abcdef abcdef'
?>
答案 1 :(得分:3)
function str_replace2($find, $replacement, $subject, $limit = 0){
if ($limit == 0)
return str_replace($find, $replacement, $subject);
$ptn = '/' . preg_quote($find,'/') . '/';
return preg_replace($ptn, $replacement, $subject, $limit);
}
这将允许您限制替换次数。应使用preg_quote
对字符串进行转义,以确保不会将任何特殊字符解释为模式字符。
如果您感兴趣,here's a version包含&$count
参数:
function str_replace2($find, $replacement, $subject, $limit = 0, &$count = 0){
if ($limit == 0)
return str_replace($find, $replacement, $subject, $count);
$ptn = '/' . preg_quote($find,'/') . '/';
return preg_replace($ptn, $replacement, $subject, $limit, $count);
}
答案 2 :(得分:2)
$str = implode($replace, explode($search, $subject, $count + 1));
快速PoC:
$str =
"To be, or not to be, that is the question:
Whether 'tis Nobler in the mind to suffer
The Slings and Arrows of outrageous Fortune,
Or to take Arms against a Sea of troubles,
And by opposing end them";
/* Replace the first 2 occurrences of 'to' with 'CAN IT' in $str. */
echo implode('CAN IT', explode('to', $str, 3));
输出(强调添加):
要是否 CAN IT ,这就是问题:
是否在心中的Nobler CAN IT 受到影响 离谱的财富的纵向和箭头,
或者来采取武器对抗麻烦的海洋,
并反对结束他们
请注意,此方法区分大小写。
答案 3 :(得分:1)
最初来自https://stackoverflow.com/a/11400172/526741
我编写了一个与str_replace()
100%向后兼容的函数。也就是说,您可以将str_replace()
的{strong>所有次出现替换为str_replace_limit()
,而不会弄乱任何内容,即使那些使用$search
,$replace
的数组,和/或$subject
。
函数可以完全自包含,如果你想用($string===strval(intval(strval($string))))
替换函数调用,但我建议反对它,因为valid_integer()
是一个相当的处理作为字符串提供的整数时的有用函数。
注意: 只要有可能,str_replace_limit()
将使用str_replace()
,因此对str_replace()
的所有调用都可以替换为str_replace_limit()
而不用担心会遇到影响。
<?php
$search = 'a';
$replace = 'b';
$subject = 'abcabc';
$limit = -1; // No limit
$new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
echo $count.' replacements -- '.$new_string;
2个替换 - bbcbbc
$limit = 1; // Limit of 1
$new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
echo $count.' replacements -- '.$new_string;
1替换 - bbcabc
$limit = 10; // Limit of 10
$new_string = str_replace_limit($search, $replace, $subject, $count, $limit);
echo $count.' replacements -- '.$new_string;
2个替换 - bbcbbc
<?php
/**
* Checks if $string is a valid integer. Integers provided as strings (e.g. '2' vs 2)
* are also supported.
* @param mixed $string
* @return bool Returns boolean TRUE if string is a valid integer, or FALSE if it is not
*/
function valid_integer($string){
// 1. Cast as string (in case integer is provided)
// 1. Convert the string to an integer and back to a string
// 2. Check if identical (note: 'identical', NOT just 'equal')
// Note: TRUE, FALSE, and NULL $string values all return FALSE
$string = strval($string);
return ($string===strval(intval($string)));
}
/**
* Replace $limit occurences of the search string with the replacement string
* @param mixed $search The value being searched for, otherwise known as the needle. An
* array may be used to designate multiple needles.
* @param mixed $replace The replacement value that replaces found search values. An
* array may be used to designate multiple replacements.
* @param mixed $subject The string or array being searched and replaced on, otherwise
* known as the haystack. If subject is an array, then the search and replace is
* performed with every entry of subject, and the return value is an array as well.
* @param string $count If passed, this will be set to the number of replacements
* performed.
* @param int $limit The maximum possible replacements for each pattern in each subject
* string. Defaults to -1 (no limit).
* @return string This function returns a string with the replaced values.
*/
function str_replace_limit(
$search,
$replace,
$subject,
&$count,
$limit = -1
){
// Set some defaults
$count = 0;
// Invalid $limit provided. Throw a warning.
if(!valid_integer($limit)){
$backtrace = debug_backtrace();
trigger_error('Invalid $limit `'.$limit.'` provided to '.__function__.'() in '.
'`'.$backtrace[0]['file'].'` on line '.$backtrace[0]['line'].'. Expecting an '.
'integer', E_USER_WARNING);
return $subject;
}
// Invalid $limit provided. Throw a warning.
if($limit<-1){
$backtrace = debug_backtrace();
trigger_error('Invalid $limit `'.$limit.'` provided to '.__function__.'() in '.
'`'.$backtrace[0]['file'].'` on line '.$backtrace[0]['line'].'. Expecting -1 or '.
'a positive integer', E_USER_WARNING);
return $subject;
}
// No replacements necessary. Throw a notice as this was most likely not the intended
// use. And, if it was (e.g. part of a loop, setting $limit dynamically), it can be
// worked around by simply checking to see if $limit===0, and if it does, skip the
// function call (and set $count to 0, if applicable).
if($limit===0){
$backtrace = debug_backtrace();
trigger_error('Invalid $limit `'.$limit.'` provided to '.__function__.'() in '.
'`'.$backtrace[0]['file'].'` on line '.$backtrace[0]['line'].'. Expecting -1 or '.
'a positive integer', E_USER_NOTICE);
return $subject;
}
// Use str_replace() whenever possible (for performance reasons)
if($limit===-1){
return str_replace($search, $replace, $subject, $count);
}
if(is_array($subject)){
// Loop through $subject values and call this function for each one.
foreach($subject as $key => $this_subject){
// Skip values that are arrays (to match str_replace()).
if(!is_array($this_subject)){
// Call this function again for
$this_function = __FUNCTION__;
$subject[$key] = $this_function(
$search,
$replace,
$this_subject,
$this_count,
$limit
);
// Adjust $count
$count += $this_count;
// Adjust $limit, if not -1
if($limit!=-1){
$limit -= $this_count;
}
// Reached $limit, return $subject
if($limit===0){
return $subject;
}
}
}
return $subject;
} elseif(is_array($search)){
// Only treat $replace as an array if $search is also an array (to match str_replace())
// Clear keys of $search (to match str_replace()).
$search = array_values($search);
// Clear keys of $replace, if applicable (to match str_replace()).
if(is_array($replace)){
$replace = array_values($replace);
}
// Loop through $search array.
foreach($search as $key => $this_search){
// Don't support multi-dimensional arrays (to match str_replace()).
$this_search = strval($this_search);
// If $replace is an array, use the value of $replace[$key] as the replacement. If
// $replace[$key] doesn't exist, just an empty string (to match str_replace()).
if(is_array($replace)){
if(array_key_exists($key, $replace)){
$this_replace = strval($replace[$key]);
} else {
$this_replace = '';
}
} else {
$this_replace = strval($replace);
}
// Call this function again for
$this_function = __FUNCTION__;
$subject = $this_function(
$this_search,
$this_replace,
$subject,
$this_count,
$limit
);
// Adjust $count
$count += $this_count;
// Adjust $limit, if not -1
if($limit!=-1){
$limit -= $this_count;
}
// Reached $limit, return $subject
if($limit===0){
return $subject;
}
}
return $subject;
} else {
$search = strval($search);
$replace = strval($replace);
// Get position of first $search
$pos = strpos($subject, $search);
// Return $subject if $search cannot be found
if($pos===false){
return $subject;
}
// Get length of $search, to make proper replacement later on
$search_len = strlen($search);
// Loop until $search can no longer be found, or $limit is reached
for($i=0;(($i<$limit)||($limit===-1));$i++){
// Replace
$subject = substr_replace($subject, $replace, $pos, $search_len);
// Increase $count
$count++;
// Get location of next $search
$pos = strpos($subject, $search);
// Break out of loop if $needle
if($pos===false){
break;
}
}
// Return new $subject
return $subject;
}
}
答案 4 :(得分:0)
这是@ brad-christie的答案的增强版本,它将数组广告兼容为$ find和$ replace值:
function str_replace_limit($find, $replacement, $subject, $limit = 0) {
if ($limit == 0)
return str_replace($find, $replacement, $subject);
for ($i = 0; $i < count($find); $i++) {
$find[$i] = '/' . preg_quote($find[$i],'/') . '/';
}
return preg_replace($find, $replacement, $subject, $limit);
}