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

PHP字符串替换问题:需排除特定17位字符内的目标子串

PHP字符串替换问题:排除特定17位字符内的目标子串

需求说明

需将字符串中所有B01至B99、L01至L99的子串替换为空格,需遵循以下规则:

  • 替换所有B01-B99、L01-L99子串为空格,但排除固定长度17位的特殊字符(如示例中的1JKFE4P03CDB05071)内部的对应内容
  • 该17位字符长度固定为17,内部可能包含B01-B99、L01-L99或其他字符
  • 该17位字符可出现在字符串任意位置,并非固定在末尾
  • 处理的字符串为动态生成,非静态

现有问题

当前PHP代码会同时替换普通字符串和17位特殊字符内的目标子串(如B05),不符合需求。

测试数据

测试字符串

$teststr = "STTARB0520122012       HT      2021B0532B        31         01283H3 BU     N   EH    2    B    20000      1JKFE4P03CDB05071";
// 另一个测试用例
// $teststr = 'PARTSB052014B062014B07HTB062029B0532BB0831B0901283H3 BUB12N EH 5 B 90000B201FDFE4FS3CDB05071 ';

现有代码

<?php
    $teststr= "STTARB0520122012       HT      2021B0532B        31         01283H3 BU     N   EH    2    B    20000      1JKFE4P03CDB05071";
    $teststr= 'PARTSB052014B062014B07HTB062029B0532BB0831B0901283H3 BUB12N EH 5 B 90000B201FDFE4FS3CDB05071 ';

    $barcodearr = array(
        "B01-B99"=>"",
        "L01-L99"=>"",
        );
        
    foreach($barcodearr as $keycode=>$val)
    {
        if(strstr($keycode, '-')) 
        {
           $barexp=explode("-",$keycode);
           $startarr = preg_split("/(,?\s+)|((?<=[a-z])(?=\d))|((?<=\d)(?=[a-z]))/i", $barexp[0]);
           $endarr = preg_split("/(,?\s+)|((?<=[a-z])(?=\d))|((?<=\d)(?=[a-z]))/i", $barexp[1]);
           $startnum=$startarr[1];
           $endnum=$endarr[1];
           $startstring=$startarr[0];

           for($i=$startnum;$i<=$endnum;$i++)
           {
                $doblechar=$i;
                if(strlen($i)!=2){
                    $doblechar='0'.$i;
                }
                
                $findh=$startstring.$doblechar;     
                
                if($startstring=='B'){
                                
                    $space='';
                    for($j=1;$j<=$i;$j++)
                    {
                        $space.='&nbsp;';
                    }
                    $teststr=str_replace($findh,$space,$teststr);
                } 
            }
        }   
    }   
?>

期望输出

$teststr = "STTAR  20122012       HT      2021 32B        31         01283H3 BU     N   EH    2    B    20000      1JKFE4P03CDB05071";

解决方案

核心思路

先通过占位符隔离17位特殊字符串,确保替换操作仅作用于普通文本部分,处理完成后再还原特殊字符串,避免误修改其内部内容。同时修正原代码中替换空格数量的逻辑(匹配期望输出,将每个Bxx/Lxx替换为与子串长度一致的两个空格)。

修正后的代码

<?php
// 测试字符串
$teststr = "STTARB0520122012       HT      2021B0532B        31         01283H3 BU     N   EH    2    B    20000      1JKFE4P03CDB05071";
// $teststr = 'PARTSB052014B062014B07HTB062029B0532BB0831B0901283H3 BUB12N EH 5 B 90000B201FDFE4FS3CDB05071 ';

// 1. 提取所有17位特殊字符串,用唯一占位符暂存
$placeholders = [];
$placeholderIndex = 0;
// 匹配17位字母数字组合(可根据实际字符范围调整正则)
$teststr = preg_replace_callback('/[A-Z0-9]{17}/i', function($matches) use (&$placeholders, &$placeholderIndex) {
    $key = "__PLACEHOLDER_{$placeholderIndex}__";
    $placeholders[$key] = $matches[0];
    $placeholderIndex++;
    return $key;
}, $teststr);

// 2. 处理普通文本部分,替换B01-B99、L01-L99为两个空格(匹配期望输出)
$teststr = preg_replace('/B(0[1-9]|[1-9]\d)/', '  ', $teststr);
$teststr = preg_replace('/L(0[1-9]|[1-9]\d)/', '  ', $teststr);

// 若需按原代码逻辑,替换为数字对应数量的空格,可使用以下回调替换:
// $teststr = preg_replace_callback('/B(0[1-9]|[1-9]\d)/', function($matches) {
//     $num = intval($matches[1]);
//     return str_repeat(' ', $num);
// }, $teststr);
// $teststr = preg_replace_callback('/L(0[1-9]|[1-9]\d)/', function($matches) {
//     $num = intval($matches[1]);
//     return str_repeat(' ', $num);
// }, $teststr);

// 3. 还原占位符为原17位特殊字符串
foreach ($placeholders as $key => $value) {
    $teststr = str_replace($key, $value, $teststr);
}

// 输出结果
echo $teststr;
?>

代码说明

  • 占位符隔离:通过preg_replace_callback提取所有17位特殊串,用唯一占位符替换,确保后续替换操作不影响这些特殊内容。
  • 正则替换:使用正则表达式精准匹配B01-B99、L01-L99,替换为符合期望的空格。
  • 还原特殊串:遍历占位符数组,将占位符替换回原17位特殊字符串,完成最终处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:32:01