$message = "[Link] Thanks [Link]";
echo str_replace(
array("[Link]", "[Link]"),
array("mylink1", "mylink2"),
$message
);
打印一个字符串:“mylink1感谢mylink1”替换多个字符串
但是,我想打印“mylink1感谢mylink2”
什么是这样做的正确方法?
$message = "[Link] Thanks [Link]";
echo str_replace(
array("[Link]", "[Link]"),
array("mylink1", "mylink2"),
$message
);
打印一个字符串:“mylink1感谢mylink1”替换多个字符串
但是,我想打印“mylink1感谢mylink2”
什么是这样做的正确方法?
您可以使用此函数作为代码中的插入替换。如@ h2ooooooo所示,它使用vsprintf
。我之前的版本失败了,因为我以错误的方式使用str_replace
的参数$count
。
function str_replace_array($search, array $replace, $subject)
{
return vsprintf(
str_replace('[Link]', '%s', $subject),
$replace);
}
$message = "[Link] Thanks [Link]";
echo str_replace_array(
"[Link]",
array("mylink1", "mylink2"),
$message
);
也许您正在寻找sprintf
?
$message = "%s Thanks %s";
echo sprintf($message, "mylink1", "mylink2"); // mylink1 Thanks mylink2
如果您更喜欢使用数组(动态变量很有用),还有vsprintf
:
$message = "%s Thanks %s";
echo vsprintf($message, array("mylink1", "mylink2")); // mylink1 Thanks mylink2
如果你真的希望不使用sprintf
或vsprintf
,你可以使用preg_replace
的第四个参数(limit
)为“1”(只在你找到的第一个匹配时才这样做)。请确保您有preg_quote
所以.
,+
,*
等使用它没有什么特别的含义:
<?php
function smartReplace($search, $replace, $subject) {
if (!is_array($search)) {
throw new Exception('$search must be an array');
}
if (!is_array($replace)) {
throw new Exception('$replace must be an array');
}
if (!is_string($subject)) {
throw new Exception('$subject must be a string');
}
for ($i = 0, $len = count($search); $i < $len; $i++) {
$subject = preg_replace('/' . preg_quote($search[$i], '/') . '/', $replace[$i], $subject, 1);
}
return $subject;
}
$message = "[Link] Thanks [Link]";
echo smartReplace(
array("[Link]", "[Link]"),
array("mylink1", "mylink2"),
$message
); // mylink1 Thanks mylink2
我纠正了[我的答案](http://stackoverflow.com/a/26014204/511529),所以它使用你的。 – GolezTrol 2014-09-24 10:20:31
可以使用preg_replace
而不是str_replace
设置限制
$message = "[Link] Thanks [Link]";
$replacements = array ("Link 1", "Link 2");
while (!empty($replacements)) {
$replacement = array_shift($replacements);
$message = preg_replace("/\[Link\]/", $replacement, $message, 1);
}
echo $message;
输出:
链接1个由于连接2
只是一个侧面说明,虽然这在大多数情况下都能正常工作,但如果替换包含'[Link]',这将会产生问题。虽然在一般情况下这不是一个问题,但在某些特殊情况下这可能是一个潜在问题。 – Gellweiler 2014-09-24 18:14:02
下面是一个例子:说你在一个在线编辑器中使用它,让用户添加链接到他们的消息。您运行过滤器来检查链接是否不包含“XSS”(以便您的平台不会成为有效载荷的启动板)。现在,攻击者可以使用有效载荷URL中的[Link]在多个链路上分割有效载荷,并以这种方式欺骗你的过滤器。这种情况可能有点构建,但我认为首先防止任何潜在的过滤器问题总是很聪明。 – Gellweiler 2014-09-24 18:33:14
一个简单的方法是结合str_replace
和vsprintf
。
$message = "[Link] Thanks [Link]";
$template = str_replace("[Link]", "%s", $message);
echo vsprintf($template, array("mylink1", "mylink2"));
试试这个
$message = "[Link] Thanks [Link]";
echo preg_replace(array("/\[Link\]/", "/\[Link\]/"),
array("mylink1", "mylink2"),
$message, 1);
我认为这会对OP和更多访问者更有帮助,当你为自己的意图添加一些解释。 – reporter 2014-09-24 10:55:34
使用vsprintf中可能是有害的,如果你可以在你的消息%
。在将[Link]
替换为%s
之前,您可以将所有出现的%
替换为%%
,然后调用vsprintf。但我只想简单地使用数组函数,这样你就不必担心正确转义的字符。
function str_replace_array($message, $search, $replacements)
{
$result = '';
$pieces = explode($search, $message);
$replace = reset($replacements);
foreach ($pieces as $i => $piece) {
if ($replace === FALSE) {
throw new Exception('There are not enough replacements for all occurences of the search string.');
}
if ($i !== 0) {
$result .= $replace;
$replace = next($replacements);
}
$result .= $piece;
}
return $result;
}
echo str_replace_array('[Link] Thanks [Link]', '[Link]', array('mylink1', 'mylink2'));
哇。在这里我正在考虑正则表达式组。做得很好。 – MoshMage 2014-09-24 10:11:26
这是一个很好的解决方案,但是您应该添加一个额外的'str_replace('%','%%',$ subject)'来转义消息中的'%'。 – Gellweiler 2014-09-24 18:16:29
如果它们来自外部,你应该用替换中的'%%'替换'%'。 – Gellweiler 2014-09-24 18:38:44