str_replace和array的使用方法

50

我在使用str_replace函数时遇到了一些问题,涉及到数组的使用。

我有如下信息:

$message = strtolower("L rzzo rwldd ty esp mtdsza'd szdepw ty esp opgtw'd dple");

我正在尝试像这样使用str_replace

$new_message = str_replace(
    array('l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k'),
    array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'),
    $message);

结果应该是主教旅馆里的一杯好酒坐在魔鬼的座位上,但实际上我得到的是p voos vlpss xn twt qxswop's wosttl xn twt stvxl's stpt

然而,当我只尝试替换两个字母时,它们被替换得很好:

$new_message = str_replace(array('l','p'), array('a','e'), $message);

字母lp将被替换为ae

如果它们的大小完全相同,为什么在完整字母表数组中无法工作?

5个回答

62

因为str_replace()从左到右进行替换,所以在进行多次替换时可能会替换先前插入的值。

    // 输出 F,因为 A 被替换成了 B,然后 B 又被替换成了 C,以此类推...
    // 最终 E 被替换成了 F,因为是按照从左到右的顺序进行替换。
    $search  = array('A', 'B', 'C', 'D', 'E');
    $replace = array('B', 'C', 'D', 'E', 'F');
    $subject = 'A';
    echo str_replace($search, $replace, $subject);

这并没有提供比其他答案中给出的更多信息(这个答案也解决了问题)。给你点踩。 - Steven Moseley
15
@TheSmose的问题是“为什么它不起作用”,而不是替代方案。因此,我试图通过一个例子来解释为什么它不起作用。 - Rakesh Tembhurne
1
另一个回答已经阐述了你上面发布的确切“为什么”,并提供了“如何解决”的方法。你以一种最简单的方式回答了问题,却没有试图解决问题,这与 SO 的初衷不符。此外,该问题已经得到了回答和解决... - Steven Moseley
1
这是一个很清晰的描述,说明了为什么会发生这种情况。谢谢。 - Novocaine
它以一种我更容易理解的方式重新构建了信息。 - alimack

49

str_replace函数在使用数组替换字符时是按顺序逐个进行替换的。建议改用strtr函数,可一次性完成所有替换操作。

$new_message = strtr($message, 'lmnopq...', 'abcdef...');

2
请注意,您可以通过执行$new_message = strtr('lmnopqrstuvwxyzabcdefghijkLMNOPQRSTUVWXYZABCDEFGHIJK','abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',$message);来使其适用于大写和小写。 - Steven Moseley

27

简单易用,优于 str_replace:

<?php
$arr = array(
    "http://" => "http://www.",
    "w" => "W",
    "d" => "D");

    $word = "http://desiweb.ir";
    echo strtr($word,$arr);
?>

strtr PHP文档 在这里


对于那些想知道的人,stristr 应该用于需要不区分大小写的应用场景。 - Tarquin
1
@Tarquin 不完全正确 - stristr 是 strstr 的不区分大小写版本,而不是 strtr(这些名称!)对于像我一样想知道的人,可以在 https://stackoverflow.com/questions/7529330/php-case-insensitive-equivalent-of-strtr 上看到替代方案。 - MortimerCat

3
除了标记为正确的答案之外,如果您需要替换单个字符而不是单个字符,则可以使用以下代码进行替换:
$query = "INSERT INTO my_table VALUES (?, ?, ?, ?);";
$values = Array("apple", "oranges", "mangos", "papayas");
foreach (array_fill(0, count($values), '?') as $key => $wildcard) {
    $query = substr_replace($query, '"'.$values[$key].'"', strpos($query, $wildcard), strlen($wildcard));
}
echo $query;

这里有一个演示: http://sandbox.onlinephpfunctions.com/code/56de88aef7eece3d199d57a863974b84a7224fd7

使用strpossubstr_replace只是使用参数$count设置为1的str_replace的冗长写法。它也存在与问题描述一致的问题。此外,该示例还存在SQL注入的风险。 - Ry-
这里更好的方法是使用 preg_replace正则表达式foreach($values as $value) { $query = preg_replace('/\\?/', $value, $query, 1); } - Erick Maeda

0
如果文本是简单的标记且具有现有锚点,请首先对现有锚点标记进行分段,替换URL,然后替换已分段标记。
$text = '
Lorem Ipsum is simply dummy text found by searching http://google.com/?q=lorem in your <a href=https://www.mozilla.org/en-US/firefox/>Firefox</a>,
<a href="https://www.apple.com/safari/">Safari</a>, or https://www.google.com/chrome/ browser.

Link replacements will first stage existing anchor tags, replace each with a marker, then swap out the remaining links.
Links should be properly encoded.  If links are not separated from surrounding content like a trailing "." period then they it will be included in the link.
Links that are not encoded properly may create a problem, so best to use this when you know the text you are processing is not mixed HTML.

Example: http://google.com/i,m,complicate--d/index.html
Example: https://www.google.com/chrome/?123&t=123
Example: http://google.com/?q='. urlencode('<a href="http://google.com">http://google.com</a>') .'
';

// Replace existing links with a marker
$linkStore = array();
$text = preg_replace_callback('/(<a.*?a>)/', function($match) use (&$linkStore){ $key = '__linkStore'.count($linkStore).'__'; $linkStore[$key] = $match[0]; return $key; }, $text);

// Replace remaining URLs with an anchor tag
$text = preg_replace_callback("/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/", function($match) use (&$linkStore){ return '<a href="'. $match[0] .'">'. $match[0] .'</a>'; }, $text);

// Replace link markers with original
$text = str_replace(array_keys($linkStore), array_values($linkStore), $text);

echo '<pre>'.$text;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接