开发者

Replace all substring instances with a variable string

开发者 https://www.devze.com 2023-03-17 21:52 出处:网络
If you had the string \'Old string Old more string Old some more 开发者_如何学JAVAstring\' and you wanted to get

If you had the string

'Old string Old more string Old some more 开发者_如何学JAVAstring'

and you wanted to get

'New1 string New2 more string New3 some more string'

how would you do it?

In other words, you need to replace all instances of 'Old' with variable string 'New'.$i. How can it be done?


An iterative solution that doesn't need regular expressions:

$str = 'Old string Old more string Old some more string';
$old = 'Old';
$new = 'New';

$i = 1;

$tmpOldStrLength = strlen($old);

while (($offset = strpos($str, $old, $offset)) !== false) {
  $str = substr_replace($str, $new . ($i++), $offset, $tmpOldStrLength);
}

$offset in strpos() is just a little bit micro-optimization. I don't know, if it's worth it (in fact I don't even know, if it changes anything), but the idea is that we don't need to search for $old in the substring that is already processed.

See Demo

Old string Old more string Old some more string
New1 string New2 more string New3 some more string


Use preg_replace_callback.

$count = 0;
$str = preg_replace_callback(
    '~Old~',
    create_function('$matches', 'return "New".$count++;'),
    $str
);


From the PHP manual on str_replace:

Replace all occurrences of the search string with the replacement string

mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )

search

The value being searched for, otherwise known as the needle. An array may be used to designate multiple needles.

replace

The replacement value that replaces found search values. An array may be used to designate multiple replacements.

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.

count

If passed, this will be set to the number of replacements performed.


Use:

$str = 'Old string Old more string Old some more string';
$i = 1;
while (preg_match('/Old/', $str)) {
    $str = preg_replace('/Old/', 'New'.$i++, $str, 1);
}
echo $str,"\n";

Output:

New1 string New2 more string New3 some more string


I had some similar solution like KingCrunch's, but as he already answered it, I was wondering about a str_replace variant with a callback for replacements and came up with this (Demo):

$subject = array('OldOldOld', 'Old string Old more string Old some more string');
$search = array('Old', 'string');
$replace = array(
    function($found, $count) {return 'New'.$count;},
    function($found, $count) {static $c=0; return 'String'.(++$c);}
);
$replace = array();

print_r(str_ureplace($search, $replace, $subject));

/**
 * str_ureplace
 *
 * str_replace like function with callback
 *
 * @param string|array search
 * @param callback|array $replace
 * @param string|array $subject
 * @param int $replace_count
 * @return string|array subject with replaces, FALSE on error.
 */
function str_ureplace($search, $replace, $subject, &$replace_count = null) {
    $replace_count = 0;

    // Validate input
    $search = array_values((array) $search);
    $searchCount = count($search);
    if (!$searchCount) {
        return $subject;
    }
    foreach($search as &$v) {
        $v = (string) $v;
    }
    unset($v);
    $replaceSingle = is_callable($replace);
    $replace = $replaceSingle ? array($replace) : array_values((array) $replace);
    foreach($replace as $index=>$callback) {
        if (!is_callable($callback)) {
            throw new Exception(sprintf('Unable to use %s (#%d) as a callback', gettype($callback), $index));
        }
    }

    // Search and replace
    $subjectIsString = is_string($subject);
    $subject = (array) $subject;
    foreach($subject as &$haystack) {
        if (!is_string($haystack)) continue;
        foreach($search as $key => $needle) {
            if (!$len = strlen($needle))
                continue;
            $replaceSingle && $key = 0;
            $pos = 0;
            while(false !== $pos = strpos($haystack, $needle, $pos)) {
                $replaceWith = isset($replace[$key]) ? call_user_func($replace[$key], $needle, ++$replace_count) : '';
                $haystack = substr_replace($haystack, $replaceWith, $pos, $len);
            }
        }
    }
    unset($haystack);

    return $subjectIsString ? reset($subject) : $subject;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消