PHP - 用于替换字符串中第n个字符的正则表达式/函数

时间:2013-04-08 07:59:27

标签: php regex string function substitution

我有一个像这样的SQL查询字符串:

SELECT * FROM `oc_product` WHERE `manufacturer_id` = ? AND `date_added` < ?  `product_id` IN (?) AND `price` > ? ORDER BY `product_id` ASC;

这将移交给Query类构造函数,如下所示:

$query = new Query("SELECT * FROM `oc_product` WHERE `manufacturer_id` = ? AND `date_added` < ?  `product_id` IN (?) AND `price` > ? ORDER BY `product_id` ASC;", 27, date("Y-m-d H:i:s"), [17,18,29,30,46,47], 27.75);

我目前有一个函数,用问号作为分隔符来爆炸字符串,计算标记的数量并遍历参数,重新组合查询字符串,因此,对于作为数组的每个参数,我都会提出它的问题标记有多个问号作为参数在数组中(因此,它不会被IN (?)更正,而是像IN (?,?,?,?,?,?)那样得到纠正。

但是,我不喜欢我的函数看起来像是什么,并希望找到一个更好的等价,或者,如果可能的话,使用正则表达式/函数/ SPL驱动的过程来使替换变得比我目前更容易。< / p>

你能给我一个提示吗?

2 个答案:

答案 0 :(得分:2)

尝试这样的事情;

$params = array(27, date("Y-m-d H:i:s"), '[17,18,29,30,46,47]', 27.75);
$counter = 0;

$query = "SELECT * FROM `oc_product` WHERE `manufacturer_id` = ? AND `date_added` < ?  `product_id` IN (?) AND `price` > ? ORDER BY `product_id` ASC;";

echo preg_replace_callback('/\?/', function($matches) {
    $GLOBALS['counter']++;

    return $GLOBALS['params'][$GLOBALS['counter']-1];
}, $query);

<强>输出

SELECT * FROM `oc_product` WHERE `manufacturer_id` = 27 AND `date_added` < 2013-04-08 10:29:43 `product_id` IN ([17,18,29,30,46,47]) AND `price` > 27.75 ORDER BY `product_id` ASC;

不确定IN ([17,18,29,30,46,47])部分,但您可以在$params数组中修改您喜欢的字符串。

祝你好运!

答案 1 :(得分:0)

找到解决方案。仅适用于SQL查询部分,但它非常快且看起来很简单:

// takes ~1.25ms to complete (on average)
function str_replace_nth($haystack, $needle, $occurrence, $replacement) {
    $tmp = explode($needle, $haystack);

    if ($occurrence > sizeof($tmp)) {
        return $haystack;
    } else {
        $tmp[$occurrence - 1] .= "{$replacement}{$tmp[$occurrence]}";
        unset($tmp[$occurrence]);
        return implode($needle, $tmp);
    }
}