Php “如何替换”;a「;加上;d"&引用;b";加上;e‘&引用;";加上;f"&引用;x";加上;“a”&引用;“是”;加上;“b”;,及;z";加上;c";?

Php “如何替换”;a「;加上;d"&引用;b";加上;e‘&引用;";加上;f"&引用;x";加上;“a”&引用;“是”;加上;“b”;,及;z";加上;c";?,php,arrays,str-replace,Php,Arrays,Str Replace,我想对字符串执行此搜索和替换,例如password 从问题中可以理解,替换后字符串应变为sdvvzrug 但不幸的是,以下代码输出了bbbbcaab: $search = range("a", "z"); $replace = array_merge(range("d", "z"), range("a", "c")); echo str_replace($search, $replace, "password"); 是什么导致了这个问题?起初我怀疑在stru replace中使用了数组,因此我

我想对字符串执行此搜索和替换,例如
password

从问题中可以理解,替换后字符串应变为
sdvvzrug

但不幸的是,以下代码输出了
bbbbcaab

$search = range("a", "z");
$replace = array_merge(range("d", "z"), range("a", "c"));
echo str_replace($search, $replace, "password");
是什么导致了这个问题?起初我怀疑在
stru replace
中使用了数组,因此我使用了一个循环,并尝试一次替换一个字符:

$search = range("a", "z");
$replace = array_merge(range("d", "z"), range("a", "c"));
$str = "password";
    for($i = 0; $i < 26; $i++)
    {
    $str = str_replace($search[$i], $replace[$i], $str);
    }
echo $str;
$search=范围(“a”、“z”);
$replace=数组合并(范围(“d”、“z”)、范围(“a”、“c”);
$str=“密码”;
对于($i=0;$i<26;$i++)
{
$str=str\u replace($search[$i],$replace[$i],$str);
}
echo$str;
令我彻底失望的是,结果还是一样。我做错了什么?我应该如何获得正确的结果?

我们开始吧

$search = range("a", "z");
$replace = array_merge(range("d", "z"), range("a", "c"));
$str = "password";
$newstr = '';
for($i = 0; $i < strlen($str); $i++)
{
    $key = array_search($str[$i],$search);
    $newstr .= $replace[$key]; 
}    
echo $newstr;
$search=范围(“a”、“z”);
$replace=数组合并(范围(“d”、“z”)、范围(“a”、“c”);
$str=“密码”;
$newstr='';
对于($i=0;$i

按顺序执行所有替换,无论字符串是派生值还是新值。而是使用一次完成所有替换:

从:

收到更换订单

因为str_replace()从左向右替换,所以在执行多次替换时,它可能会替换以前插入的值

我对
for
循环进行了一些修改,以帮助您了解如何获得该输出:

<?php

$str = "password";
$search = range("a", "z");
$replace = array_merge(range("d", "z"), range("a", "c"));

header('Content-Type: text/plain');

for($i = 0; $i < 26; $i++)
{
    $beforeStr = $str;
    $str = str_replace($search[$i], $replace[$i], $str);

    //var_dump($search[$i], $replace[$i], $str);

    if ($beforeStr !== $str) {
        echo "$i) $search[$i] -> $replace[$i]\n";
        echo "Replacement: $before -> $str";
    } else {
        echo "$i) $search[$i] -> $replace[$i]\n";
        echo "Replacement: none";
    }
    echo "\n\n";
}

echo $str;



注意:不要尝试推出自己的加密算法或协议这极易出错。使用经过尝试和测试的库。请参阅,以了解为什么不应该推出自己的加密算法。

进行这种多次替换是错误的。使用strtr将解决此问题,因为它不会更改已替换的字符

这就是你得到BBCAAB的原因:

    :password
a->d:pdssword
b->e:pdssword
c->f:*
d->g:pgssworg
e->h:*
f->i:*
g->j:pjssworj
h->k:*
i->l:*
j->m:pmssworm
k->n:*
l->o:*
m->p:ppssworp
n->q:*
o->r:ppsswrrp
p->s:sssswrrs
q->t:*
r->u:sssswuus
s->v:vvvvwuuv
t->w:*
u->x:vvvvwxxv
v->y:yyyywxxy
w->z:yyyyzxxy
x->a:yyyyzaay
y->b:bbbbzaab
z->c:bbbbcaab

其他答案已经解释了如何做到这一点,因此我将重点关注“我做错了什么?”部分

因此,您的
for
-循环相当于:

$str = str_replace('a', 'd', $str);
$str = str_replace('b', 'e', $str);
$str = str_replace('c', 'f', $str);
$str = str_replace('d', 'g', $str);
$str = str_replace('e', 'h', $str);
$str = str_replace('f', 'i', $str);
$str = str_replace('g', 'j', $str);
// ...
$str = str_replace('z', 'c', $str);
如您所见,这种“扫视”字母表:
a
d
替换,随后
d
g
替换,随后
g
j
替换。问题是,当您将
d
替换为
g
时,无论
d
代表的是最初的
d
还是最初的
a
,您都在这样做。每个
stru\u replace
都在丢弃信息;在第一行之后,您无法判断字符串
ddd
最初是
add
,还是最初是
dad
,当您将
d
更改为
g
时,您会得到
ggg
,而不是
dgg
gdg
等等


只有一个
str_replace
的版本产生相同结果的原因是
str_replace
与您的循环做相同的事情:它只是在搜索数组上迭代,执行替换,并且不确保它从不“重新替换”子字符串。这就是为什么您需要使用专门为此目的而设计的方法,例如
strtr

请参阅正确的实现:
stru rot('password',3)如果您仍然喜欢进行字符替换,请尝试使用strtr而不是str_replace。这通常称为。
$str = str_replace('a', 'd', $str);
$str = str_replace('b', 'e', $str);
$str = str_replace('c', 'f', $str);
$str = str_replace('d', 'g', $str);
$str = str_replace('e', 'h', $str);
$str = str_replace('f', 'i', $str);
$str = str_replace('g', 'j', $str);
// ...
$str = str_replace('z', 'c', $str);