PHP:str_replace 问题

发布于 2024-10-21 23:47:17 字数 519 浏览 6 评论 0 原文

我注意到 str_replace 函数的奇怪行为。 您能告诉我为什么我得到的是 no_4 而不是 no_2 中的数字 3 吗?

情况如下:

$pattern = array(1,2,3);
$change = array(1,3,4); 
$sql = "SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN (%s) AND no_3 IN (%s)";

$test_multiply[] = str_replace($pattern, $change, $sql);

哪个给出:

Array ( [0] => SELECT * FROM %s WHERE no_1 IN (%s) AND no_4 IN (%s) AND no_4 IN (%s) ) 

你能告诉我我应该做什么才能收到 no_3 而不是 no_2?

I have noticed a strange behaviour of a str_replace function.
Can you tell me why instead of number 3 in no_2 i get no_4 ?

Here is the case:

$pattern = array(1,2,3);
$change = array(1,3,4); 
$sql = "SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN (%s) AND no_3 IN (%s)";

$test_multiply[] = str_replace($pattern, $change, $sql);

Which gives:

Array ( [0] => SELECT * FROM %s WHERE no_1 IN (%s) AND no_4 IN (%s) AND no_4 IN (%s) ) 

Can you tell me what should I do to receive no_3 instead of no_2?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

℡寂寞咖啡 2024-10-28 23:47:17

str_replace() 的文档说 < em>(引用):

因为str_replace()将 left 替换为
是的,它可能会取代以前的
执行多个操作时插入的值
替代品。

我相信您正是处于这种情况:

  • 您的 no_2 被替换为 no_3 - 因为您的 $pattern 中的 第二$change 数组
  • 但是,由于 thidno_3 被替换为 no_4在您的 $pattern$change 数组中添加

To avoid that specific situation, you might try reversing the order of the items in those two arrays :

$pattern = array(3, 2, 1);
$change = array(4, 3, 1); 

,您会得到以下结果:

SELECT * FROM %s WHERE no_1 IN (%s) AND no_3 IN (%s) AND no_4 IN (%s)

The documentation for str_replace() says (quoting) :

Because str_replace() replaces left to
right, it might replace a previously
inserted value when doing multiple
replacements.

I believe you are precisely in this situation :

  • Your no_2 gets replaced to no_3 -- because of the second item in your $pattern and $change arrays
  • But, then, that no_3 gets replaced to no_4 -- because of the thid item in your $pattern and $change arrays

To avoid that specific situation, you might try reversing the order of the items in those two arrays :

$pattern = array(3, 2, 1);
$change = array(4, 3, 1); 

And you'd get the following result :

SELECT * FROM %s WHERE no_1 IN (%s) AND no_3 IN (%s) AND no_4 IN (%s)
生生漫 2024-10-28 23:47:17

如果您将 str_replace 与一组针一起使用,则每个针都会被替换为单独的 <代码>str_replace调用。您可以想象类似的事情在内部发生:

for ($i=0, $n=min(count($pattern),count($change)); $i<$n; $i++) {
    $sql = str_replace($pattern[$i], $change[$i], $sql);
}

因此在第一次迭代中,所有 1 都被 1 替换,然后所有 2 都被 < code>3,然后将所有 3 替换为 4

  1. SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN ( %s) AND no_3 IN (%s)
  2. 从 %s 中选择 *,其中 no_1 IN (%s) AND no_3 IN (%s) AND no_3 IN (%s)
  3. SELECT * FROM %s WHERE no_1 IN (%s) AND no_4 IN (%s) AND no_4 IN (%s)

要进行同时替换,您可以使用 preg_replace_callback 并为每个匹配的模式调用映射函数:

function str_replacep(array $search, array $replace, $subject, &$count=0) {
    $combinedPattern = '/(?:'.implode('|', array_map(function($str) { return preg_quote($str, '/'); }, $search)).')/';
    $map = array_combine($search, $replace);
    $mapping = function($match) use ($map, $count) {
        $count++;
        return $map[$match[0]];
    };
    return preg_replace_callback($combinedPattern, $mapping, $subject);
}

我使用 匿名函数,但它也适用于 create_function

这样,替换的顺序就不再重要了。您甚至可以交换两个值:

var_dump(str_replacep(array(1,2), array(2,1), "12"));  // string(2) "21"

If you use str_replace with an array of needles, every needle is replaced in a separate str_replace call. You can imagine that something like this happens internally:

for ($i=0, $n=min(count($pattern),count($change)); $i<$n; $i++) {
    $sql = str_replace($pattern[$i], $change[$i], $sql);
}

So in the first iteration all 1 are replaced by 1, then all 2 are replaced by 3, and then all 3 is replaced by 4:

  1. SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN (%s) AND no_3 IN (%s)
  2. SELECT * FROM %s WHERE no_1 IN (%s) AND no_3 IN (%s) AND no_3 IN (%s)
  3. SELECT * FROM %s WHERE no_1 IN (%s) AND no_4 IN (%s) AND no_4 IN (%s)

To do a simultaneous replacement, you can use preg_replace_callback and call a mapping function for each matched pattern:

function str_replacep(array $search, array $replace, $subject, &$count=0) {
    $combinedPattern = '/(?:'.implode('|', array_map(function($str) { return preg_quote($str, '/'); }, $search)).')/';
    $map = array_combine($search, $replace);
    $mapping = function($match) use ($map, $count) {
        $count++;
        return $map[$match[0]];
    };
    return preg_replace_callback($combinedPattern, $mapping, $subject);
}

I used anonymous function in this example but it will also work with create_function.

With this the order of the replacement doesn’t matter. You can even exchange two values:

var_dump(str_replacep(array(1,2), array(2,1), "12"));  // string(2) "21"
相守太难 2024-10-28 23:47:17

首先,您将 1 替换为 1,这样就可以了

SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN (%s) AND no_3 IN (%s)

然后,替换 2与 3 一起,得到

SELECT * FROM %s WHERE no_1 IN (%s) AND no_3 IN (%s) AND no_3 IN (%s)

然后将 3 替换为 4,结果是
SELECT * FROM %s WHERE no_1 IN (%s) AND no_4 IN (%s) AND no_4 IN (%s)

也许您应该将 2 替换为另一个值(而不是 3),您可以将其替换稍后再来。

First, you're replacing 1 with 1, so thats fine

SELECT * FROM %s WHERE no_1 IN (%s) AND no_2 IN (%s) AND no_3 IN (%s)

Then, replacing 2 with 3, to get

SELECT * FROM %s WHERE no_1 IN (%s) AND no_3 IN (%s) AND no_3 IN (%s)

Then replacing 3 with 4, resulting in
SELECT * FROM %s WHERE no_1 IN (%s) AND no_4 IN (%s) AND no_4 IN (%s)

Maybe you should replace 2 with another value (not 3), which you can replace again later.

拥有 2024-10-28 23:47:17

因为一旦你将 2 替换为 3,下一次替换将始终将 3 替换为 4

Because once you replace 2 with 3 the next replace will always replace 3 with 4

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文