【问题标题】:Replacing all occurrences of a string with values from an array用数组中的值替换所有出现的字符串
【发布时间】:2013-04-15 15:50:51
【问题描述】:

我在将字符串发送到数据库之前对其进行解析。我想遍历该字符串中的所有 <br> 并将它们替换为我从数组中获得的唯一数字,然后是 newLine。

例如:

str = "Line <br> Line <br> Line <br> Line <br>"
$replace = array("1", "2", "3", "4");

my function would return 
"Line 1 \n Line 2 \n Line 3 \n Line 4 \n"

听起来很简单。我只会做一个while循环,使用strpos获取&lt;br&gt;的所有出现,然后使用str_replace将它们替换为所需的数字+\n。

问题是我总是得到一个错误,我不知道我做错了什么?可能是一个愚蠢的错误,但仍然很烦人。

这是我的代码

$str     = "Line <br> Line <br> Line <br> Line <br>";
$replace = array("1", "2", "3", "4");
$replaceIndex = 0;

while(strpos($str, '<br>') != false )
{
    $str = str_replace('<br>', $replace[index] . ' ' .'\n', $str); //str_replace, replaces the first occurance of <br> it finds
    index++;
}

有什么想法吗?

提前致谢,

【问题讨论】:

  • 首先,在第一次迭代中,您将替换 &lt;br&gt;... 的所有实例。要这样做,您只需使用 substr_replace 替换字符串的一部分这使您可以定义替换的位置。

标签: php string loops phpmyadmin


【解决方案1】:

我会使用正则表达式和自定义回调,如下所示:

$str = "Line <br> Line <br> Line <br> Line <br>";
$replace = array("1", "2", "3", "4");
$str = preg_replace_callback( '/<br>/', function( $match) use( &$replace) {
    return array_shift( $replace) . ' ' . "\n";
}, $str);

请注意,这假设我们可以修改 $replace 数组。如果不是这样,您可以保留一个计数器:

$str = "Line <br> Line <br> Line <br> Line <br>";
$replace = array("1", "2", "3", "4");
$count = 0;
$str = preg_replace_callback( '/<br>/', function( $match) use( $replace, &$count) {
    return $replace[$count++] . ' ' . "\n";
}, $str);

你可以从this demo看到这个输出:

Line 1 Line 2 Line 3 Line 4 

【讨论】:

  • 您的回答有效,并且 str 被正确解析,但由于某种原因,当我调用 INSERT INTO 时它没有被插入到数据库中。任何想法为什么?
  • @r3x - 怎么会?你有错误信息吗?如果您希望打印文字 \n 字符而不是让 PHP 将其解释为换行符,请将 "\n" 周围的双引号更改为单引号。
  • 这是我的插入查询(interestTable 基本上是解析后的字符串)。 mysql_query("INSERT INTO $tbl_name(userID,storyID,rank, storyType, interestTable)VALUES('$userID','$storyID','$rank','$storyType','$interestTable')", $dbh1); 如果我从这个查询中删除了 interestTable 的值,那么一切正常,但如果我添加它,则什么都不会发送。至于错误,我没有得到任何错误。奇怪:S
  • 我认为字符串内容的格式不正确。连“Line 1 \nLine 2\nLine 3\nLine 4\n”都没有插入到DB,所以不是大小问题。
  • 如果没有错误消息或更多信息,就无法判断出了什么问题。
【解决方案2】:

如果你只是想数,你也可以用这个。

$str_expl = explode('<br>',$str);
foreach($str_expl as $index=>&$str)
    if(!empty($str))
        $str .= ($index+1);
$str = implode($str_expl);

【讨论】:

  • 如果要将找到的项替换为自己的数组,可以将str .= ($index+1)改为str .= $myArray[index];
【解决方案3】:
$str = str_replace('<br>', $replace[$index] . ' ' .'\n', $str);

这是替换 ALL 它发现的 &lt;br&gt; 的出现。

正确的是每次迭代只做一次替换:substr_replace 可以替换字符串的一个部分。正确的是:

while($pos = strpos($str, '<br>') !== false )
{
    $str = substr_replace($str, $replace[$replaceIndex] . ' ' .'\n', $pos, 4); // The <br> is four bytes long, so 4 bytes from $pos on.
    $replaceIndex++;
}

(别忘了replaceIndex之前的$$replaceIndex是一个变量)

【讨论】:

  • str_replace的第4个参数不是要替换多少次。这是一个设置为它确实替换了多少次的参考。
【解决方案4】:

你需要记住变量前面的$。另外,尝试使用php regex function,它允许指定替换的数量。

<?php
$str     = "Line <br> Line <br> Line <br> Line <br>";
$replace = array("1", "2", "3", "4");
$index = 0;
$count = 1;

while(strpos($str, '<br>') != false )
{
    $str = preg_replace('/<br>/', $replace[$index] . " \n", $str, 1); //str_replace, replaces the first occurance of <br> it finds
    $index++;
}
echo $str
?>

【讨论】:

  • 最后一个参数不允许你设置替换次数。这是一个设置为它确实做的替换次数的参考。
  • 我指的是preg_replace中的$limit变量。
  • 我以为您使用的是$count 参数。没关系:-)
  • 啊,我看到你在回答我下面的答案!
  • 这需要在字符串上应用 N 个正则表达式,如果字符串包含大量 &lt;br&gt; 元素,这会降低性能。
【解决方案5】:

这是我的版本。 8 行格式化,没有正则表达式,KISS。

$str = "Line <br> Line <br> Line <br> Line <br>";
$replace = array("1", "2", "3", "4");

$temp = explode("<br>", $str);
$result = "";
foreach ($temp as $k=>$v) {
    $result .= $v;
    if ($k != count($temp) - 1) {
        $result .= $replace[$k];
    }
}

echo $result;

【讨论】:

    【解决方案6】:

    preg_replace_callback 将帮助您操作替换过程,nickb 的回答显示了如何完成。

    但是,匹配项的数量可能多于 $replace 数组中的项目数量。如果您想从第 0 项重新开始使用其元素,您需要在计数器等于$replace 数组大小时重置

    PHP demo

    $text = "Line <br> Line <br> Line <br> Line <br> Line <br> Line <br>";
    $replace = array("1", "2", "3", "4");
    $counter = 0;
    $text = preg_replace_callback('~<br\s*/?>~', function($m) use($replace, &$counter) {
        if ($counter === count($replace)) { $counter = 0; }
        return $replace[$counter++];
    }, $text);
    echo $text;
    

    输出:Line 1 Line 2 Line 3 Line 4 Line 1 Line 2

    请注意,&lt;br\s*/?&gt; 正则表达式匹配可以自闭合的br 标记(/? 匹配可选的/ 字符,并且为了保持/ 在模式中未转义,我使用了@ 987654335@ char 作为regex delimiter) 并且在br 之后和/&gt; / &gt; 之前可能包含零个或多个空格(\s*)。

    【讨论】:

      猜你喜欢
      • 2017-03-20
      • 2012-08-01
      • 2021-12-27
      • 2022-11-21
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 2014-08-05
      • 2019-01-10
      相关资源
      最近更新 更多