简体   繁体   English

如何替换字符串中的第n个匹配项

[英]How to replace a nth occurrence in a string

I need a simple and fast solution to replace nth occurrence (placeholder) in a string. 我需要一个简单快速的解决方案来替换字符串中的第n个出现位置(占位符)。

For example, nth question mark in sql query should be replaced with a provided value. 例如,sql查询中的第n个问号应替换为提供的值。

$subject = "SELECT uid FROM users WHERE uid = ? or username = ?";

So, i need function like str_replace_nth($seach, $replace, $subject, $nth) and for second question mark it should be called as str_replace_nth("?", $username, $subject, 2); 所以,我需要像str_replace_nth($seach, $replace, $subject, $nth)这样的函数,对于第二个问号,它应该称为str_replace_nth("?", $username, $subject, 2);

Any ideas? 有任何想法吗?

PS Please, don't suggest me to use PDO, because I'm working on FDO (Facebook Data Object) a library with an interface similar to PDO, but for FQL. PS:请不要建议我使用PDO,因为我正在使用FDO(Facebook数据对象)一个具有与PDO类似的接口的库,但用于FQL。

Important notice! 重要的提醒! I've figured out that this approach is bad because after first replacement the query is modified and indexes are lost. 我发现这种方法不好,因为在第一次替换之后,查询被修改并且索引丢失。 (Bad approaches come when you're programming late at night :() So, as @GolezTrol mention in comment, it's better to replace all at once. (当您在深夜编程时,会出现错误的方法:()因此,正如@GolezTrol在评论中提到的,最好一次全部替换掉​​。

Here is the function you asked for: 这是您要求的功能:

$subject = "SELECT uid FROM users WHERE uid = ? or username = ?";

function str_replace_nth($search, $replace, $subject, $nth)
{
    $found = preg_match_all('/'.preg_quote($search).'/', $subject, $matches, PREG_OFFSET_CAPTURE);
    if (false !== $found && $found > $nth) {
        return substr_replace($subject, $replace, $matches[0][$nth][1], strlen($search));
    }
    return $subject;
}

echo str_replace_nth('?', 'username', $subject, 1);

Note: $nth is a zero based index! 注意: $nth是从零开始的索引!

But I'll recommend to use something like the following to replace the placeholders: 但我建议使用类似以下的内容替换占位符:

$subject = "SELECT uid FROM users WHERE uid = ? or username = ?";

$args = array('1', 'steve');
echo vsprintf(str_replace('?', '%s', $subject), $args);

Instead of using question marks, why don't use markers like that : 除了使用问号之外,为什么不使用这样的标记:

$subject = "SELECT uid FROM users WHERE uid = :uid or username = :username";
$parameters = array(
    ':uid' => 42,
    ':username' => 'John',
);
$subject = str_replace(array_keys($parameters), $parameters, $subject);

Validation on input parameter not done 输入参数验证未完成

 function str_replace_nth($search, $replace, $subject, $nth){
  $match_arr = explode($search,$subject);
  $match_arr = array_filter($match_arr);

   foreach($match_arr as $key=>$val){

      if($key == $nth-1){ // array index start with Zero
        $match_arr[$key] .=  $replace;
      }else{
        $match_arr[$key] .=  '?';
      }

   }
   return implode('',$match_arr);
}

None of your solutions worked for me, so I made this: 您的解决方案都不适合我,因此我做到了:

$sql1 = "SELECT * FROM allegro_user WHERE User_Emp_Nb = ? AND User_Activ_status = ?";
$sql2 = "SELECT * FROM allegro_user WHERE User_Emp_Nb = :emp_nb AND User_Activ_status = :activ";

function prepare_query($sql, $args) {
    foreach ($args as $key => $value) {
        if (is_numeric($key)) {
            $sql = preg_replace('/\?/', "'" . $value . "'", $sql, 1);
        } else {
            $sql = str_replace($key, "'" . $value . "'", $sql);
        }
    }
    return $sql;

}

tab($sql1);
$sql = prepare_query($sql1, array('0216313', 'A'));
tab($sql1);

tab($sql2);
$sql = prepare_query($sql2, array(':emp_nb' => '0216313', ':activ' => 'A'));
tab($sql2);

tab() is just a function I use for printing : tab()只是我用于打印的功能:

echo '<pre>';
print_r($tab);
echo '</pre>';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM