【问题标题】:How to replace the first occurrence in a string?如何替换字符串中的第一次出现?
【发布时间】:2015-11-11 23:13:39
【问题描述】:

我正在尝试替换每个问号“?”在具有数组值的字符串中。

我需要遍历一个字符串,并替换第一次出现的 '?'在带有值的字符串中。每次出现我都需要这样做

这是我尝试过的

function sprintf2($str='', array $values = array(), $char = '?')
{
    if (!$str){
        return '';
    }

    if (count($values) > 0)
    {
        foreach ($values as $value)
        {
            $str = preg_replace('/'. $char . '/', $value, $str, 1);
        }
    }

    echo $str;
}

但我得到以下异常

preg_replace(): 编译失败:偏移 0 处没有可重复的内容

下面显示了我是如何调用函数的

    $bindings = array(10, 500);
    $str = "select * from `survey_interviews` where `survey_id` = ? and `call_id` = ? limit 1";
    sprintf2($str, $bindings);

我在这里做错了什么?为什么会出现这个异常?

【问题讨论】:

  • 您可能会从准备好的语句中受益。看看这个example at php.net。还有this one.
  • @showdev 我实际上想打印正在服务器上执行的实际查询。我想用纯文本打印它来评估它的价值

标签: php regex replace preg-replace


【解决方案1】:

使用str_replace 而不是preg_replace,因为您要替换的是文字字符串,而不是正则表达式模式。

但是,str_replace 总是替换所有匹配项,无法将其限制为仅第一个匹配项(preg_replace 类似)。第 4 个参数不是限制,它是一个变量,设置为找到并替换的匹配数。要仅替换一个匹配项,您可以组合 strpossubstr_replace

function sprintf2($str='', array $values = array(), $char = '?')
{
    if (!$str){
        return '';
    }

    if (count($values) > 0)
    {
        $len = strlen($char);
        foreach ($values as $value)
        {
            $pos = strpos($str, $char);
            if ($pos !== false) {
                $str = substr_replace($str, $value, $pos, strlen($char));
            }
        }
    }

    echo $str;
}

DEMO

【讨论】:

  • 同意。 “如果你不需要花哨的替换规则(比如正则表达式),你应该总是使用这个函数而不是 preg_replace()。” str_replace @ php.net
  • @Barmar 这对我不起作用。首先,我将数字 1 替换为以数字 1 作为值的值。现在它似乎用相同的值替换了每次出现。根据您的代码应该可以工作的文档。这是我的代码$count = 1; foreach ($bindings as $value) { $sql = str_replace('?', $value, $sql, $count); } echo $sql .'<br>';
  • 我们都误解了 $countstr_replacepreg_replace 的参数。这不是对替换次数的限制,它是一个参考参数,用于获取已进行的替换次数。
【解决方案2】:

您需要转义“?”使用反斜杠('\?' 而不是 '?')登录您的正则表达式。

但是您的代码可以很容易地重构为使用 preg_replace_callback:

$params = array(1, 3);
$str = '? bla ?';
echo preg_replace_callback('#\?#', function() use (&$params) {
    return array_pop($params);
}, $str);

【讨论】:

  • 由于该函数以字符串为参数,所以应该使用preg_quote转义。
【解决方案3】:

希望此代码对您有所帮助。

function sprintf2($string = '', array $values = array(), $char = '?')
{
    if (!$string){
        return '';
    }

    if (count($values) > 0)
    {
        $exploded = explode($char, $string);
        $i = 0;
        $string = '';
        foreach ($exploded as $segment) {
            if( $i < count($values)){
                $string .= ($segment . $values[$i]);
                ++$i;
            }

        }
    }

    echo $string;
}

$bindings = array(10, 500);
$str = "select * from `survey_interviews` where `survey_id` = ? and `call_id`= ? limit 1";
echo sprintf2($str, $bindings);


说明:
在您的代码中,您使用的是 preg_match 并且 preg_match 方法中的第一个参数是正则表达式模式。您要替换的是 ?0 或 1 CHARACTER 具有有效含义。所以,你必须通过 \? 来避免这种情况。尽管不需要对所有字符进行转义,但为了使您的方法正常工作,您必须检查对任何正则表达式都有效的字符。
在我的代码中,我已将字符串拆分为您想要的字符。然后将值附加到我们从数组中获得的部分的末尾。并且这应该直到值数组的值长度才完成,否则会发生偏移错误。

【讨论】:

  • 解释一下会很有帮助。问题是什么,你的代码是如何解决的?
猜你喜欢
  • 2020-05-22
  • 2012-06-09
  • 2011-06-05
  • 2011-08-25
  • 2016-11-02
  • 2018-07-31
相关资源
最近更新 更多