You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP刽子手游戏:字符替换为下划线的函数问题求助

解决字符隐藏替换为下划线的问题

我来帮你分析下现有代码的问题,再给出能实现需求的解决方案~

先拆解现有代码的问题

代码段1的问题

  • 用sizeof($answer)获取字符串长度不合适,sizeof是为数组设计的,字符串应该用strlen()(如果是多字节字符要改用mb_strlen()),虽然部分场景下sizeof能返回字节数,但语义不对,还可能在多字节场景下出错。
  • str_replace($hidden[$element], '_', $hidden, $replace_count)会替换所有和目标位置相同的字符,而非仅替换当前位置。比如单词是"apple",若取到的字符是'l',会直接把两个'l'都换成下划线,导致$count瞬间累加2,可能直接超过你设定的$hideCount,而且会把重复字符全部替换,不符合“部分替换”的需求。
  • 循环逻辑有bug:每次固定取sizeof($answer)-2这个位置,如果该位置已经是下划线,循环会陷入死循环,因为$count不会增加。

代码段2的问题

这段代码只是把原字符串存到Session里,然后直接返回原字符串,完全没有执行任何字符替换操作,自然达不到隐藏效果。

正确的实现方案

我们的目标是:按指定数量替换字符为下划线,且每个位置仅替换一次,不会批量替换重复字符。以下是两种场景的实现:

单字节字符版本(适用于英文、数字等)

function hide($answer) {
    $strLength = strlen($answer);
    // 和你原逻辑保持一致,计算需要隐藏的字符数
    $hideCount = floor($strLength / 2) + 1;
    // 边界处理:避免隐藏数量超过总字符数(比如短单词场景)
    $hideCount = min($hideCount, $strLength);
    
    // 把字符串转成数组,方便单个字符操作
    $hidden = str_split($answer);
    // 生成所有字符的位置数组
    $positions = range(0, $strLength - 1);
    // 打乱位置,实现随机隐藏效果
    shuffle($positions);
    
    $count = 0;
    foreach ($positions as $pos) {
        if ($count >= $hideCount) {
            break;
        }
        // 只替换非下划线的字符,避免重复替换
        if ($hidden[$pos] !== '_') {
            $hidden[$pos] = '_';
            $count++;
        }
    }
    
    // 把数组转回字符串返回
    return implode('', $hidden);
}

多字节字符版本(适用于中文、特殊字符等)

如果你的字符串包含多字节字符(比如中文),需要用多字节字符串函数处理避免乱码:

function hide($answer) {
    $strLength = mb_strlen($answer);
    $hideCount = floor($strLength / 2) + 1;
    $hideCount = min($hideCount, $strLength);
    
    $hidden = mb_str_split($answer);
    $positions = range(0, $strLength - 1);
    shuffle($positions);
    
    $count = 0;
    foreach ($positions as $pos) {
        if ($count >= $hideCount) {
            break;
        }
        if ($hidden[$pos] !== '_') {
            $hidden[$pos] = '_';
            $count++;
        }
    }
    
    return implode('', $hidden);
}

代码逻辑说明

  1. 先获取字符串长度,计算需要隐藏的字符数,同时做边界处理避免逻辑错误。
  2. 将字符串转成数组,方便逐个操作单个字符。
  3. 生成所有字符位置的数组并打乱,实现随机隐藏(如果需要固定位置替换,比如替换前N个字符,去掉shuffle($positions),直接遍历前N个位置即可)。
  4. 遍历打乱后的位置,逐个替换非下划线字符,直到达到需要隐藏的数量。
  5. 最后将数组转回字符串返回。

内容的提问来源于stack exchange,提问作者edeath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:29:55