避免在替换字符串中找到替换占位符

时间:2019-06-22 08:24:05

标签: php regex preg-replace

假设我有这个字符串:

"my string ? other string ?"
  • 我要替换第一个“?”与"first param ?"(在文本内注意占位符?)
  • 和第二个"second param".

如果我做一个preg_replace,我会得到这个:

my string first param second param other string ?
          ^^^^^^^^^^^^^^^^^^^^^^^^              ^
                WRONG                    NOT REPLACED

基本上,因为第一个替换项还具有占位符,所以preg_replace愚蠢到足以替换该占位符,而不是最后一个真正的第二个占位符。

带有preg_replace的代码:

$search = ["?", "?"];
$params = ["first param ?", "second param"];
$query ="first text ? other text ?";

//> Marker in the query are ?, so I create the array to preg_replace
$search = array_fill(0,count($params),'/\?/');
$query = preg_replace(
    $search,                // a list of ?
    $params,                // escaped values
    $query,                 // from query
    1                       // replace only 1 time
);
//output: first text first param second param other text ?

关于如何避免在替换中搜索占位符的任何提示吗?

带有preg_replace的实时代码:http://sandbox.onlinephpfunctions.com/code/e705ba454d030103344bc826e0fe0bf42d5b7b90

也不能与str_replace

一起使用
$search = ["?", "?"];
$params = ["first param ?", "second param"];
$query ="first text ? other text ?";

$query = str_replace ($search, $params, $query);
echo $query;

// output: first text first param second param other text first param second param

带有str_replace的实时代码: http://sandbox.onlinephpfunctions.com/code/dc259325411ee42de759f145eac78b339f329f74

输出异常

给出:

$search = ["?", "?"];
$params = ["first param ?", "second param"];
$query ="first text ? other text ?";

预期输出为:

first text first param ? other text second param
           ^^^^^^^^^^^^^            ^^^^^^^^^^^^
         first placeholder         second placeholder

具有3个参数的输出除外

$search = ["?", "?", "?"];
$params = ["first param", "second param ?", "third param"];
$query ="first text ? other text ? other chunk ?";

预期输出为:

first text first param other text  second param ? other chunk third param
           ^^^^^^^^^^^^^            ^^^^^^^^^^^^              ^^^^^^^^^
         first placeholder         second placeholder         third placeholder

我的自定义解决方案

我已经使用preg_split提出了一个可行的解决方案,但是说实话,这是如此棘手,必须有更好的东西:

 $parts = preg_split('/(\?)/', $query, -1, PREG_SPLIT_DELIM_CAPTURE);

 foreach($parts as $k=>&$v) {
        // if is odd, then it's a placeholder
        if ($k%2 == 1)
            $v = $params[$k/2];  // replace placeholder with a param
 }

 $query = implode('',$parts);

4 个答案:

答案 0 :(得分:3)

任何自定义替换逻辑都应使用array( 'id' => '1', array( 'nom' => 'test', 'titre' => 'test', 'auteur' => 'test', ), 'id' => '2', array( 'nom' => 'test2', 'titre' => 'test2', 'auteur' => 'test2', ), ); 来实现,例如:

preg_replace_callback

实时代码:http://sandbox.onlinephpfunctions.com/code/33f4804b49103e54e8070e8d9959ec9642930857

答案 1 :(得分:2)

这可以通过使用T循环并检查while()来完成,但是strpos()是解决此问题的另一种方法:

explode()

请参见live demo here

答案 2 :(得分:1)

这仅适用于2个占位符。

$search = [
    "/^([^?]*)\?/",     # matches everything that is not a question mark in group 1, then a question mark
    "/^(.*)\?/"         # matches everything until last question mark in group 1, then a question mark
];
$params = ["$1first param ?", "$1second param"];

$query = "first text ? other text ?";

$query = preg_replace($search, $params, $query);

echo $query;

输出:

first text first param ? other text second param

答案 3 :(得分:0)

尝试:

$s = "my string ? other string ?";
$s = preg_replace('/\?/', "first ?", $s, 1);
$s = preg_replace('/((?:^.*?\?)?.*?)\?/', "$1second text", $s);
echo $s;

基于How to skip first regex match?