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

PHP:字符串包含指定子串且排除其他子串的编码分配优化实现咨询

你的问题我太懂了——手动写一堆if-else处理多颜色组合不仅容易出错,扩展性还极差,尤其是要支持6种颜色、10个对象的场景,简直是维护噩梦。先帮你拆解下原来代码的问题,再给你一个简洁可复用的方案:

先说说你原来代码的问题

你的else if顺序是先判断单个颜色(比如red),再判断组合(red+blue)。当字符串同时包含red和blue时,第一个判断strpos($mystring, 'red')就会命中,直接把code设为2,根本轮不到后面的组合判断。这是逻辑顺序的硬伤,而且就算调整顺序,手动写所有组合也会让代码量爆炸。

简洁可复用的解决方案

核心思路是把匹配规则和业务逻辑分离:用配置数组定义所有规则(从优先级高的组合到低优先级的单个),然后封装成通用函数来处理匹配。这样不管是新增颜色、组合,还是切换到其他对象,只需要修改配置数组就行,完全不用碰核心逻辑。

代码示例

/**
 * 根据字符串包含的子串组合返回对应编码
 * @param string $string 待匹配的字符串
 * @param array $rules 匹配规则数组,每个元素包含['substrings' => [...], 'code' => 数字]
 * @param string $baseSubstr 基础对象(比如balloon)
 * @param int $baseCode 仅包含基础对象时的编码
 * @return int|null 匹配到的编码,无匹配或无基础对象时返回null
 */
function getTargetCode($string, $rules, $baseSubstr, $baseCode) {
    // 先检查基础对象是否存在,不存在直接返回
    if (strpos($string, $baseSubstr) === false) {
        return null;
    }

    // 按优先级遍历规则,找到第一个匹配的就返回编码
    foreach ($rules as $rule) {
        // 用正向预查正则确保所有子串都存在(比多次strpos更简洁)
        $pattern = '/';
        foreach ($rule['substrings'] as $substr) {
            // 转义特殊字符,避免正则报错
            $pattern .= '(?=.*' . preg_quote($substr, '/') . ')';
        }
        $pattern .= '/i'; // 可选:i表示不区分大小写,根据需求调整

        if (preg_match($pattern, $string)) {
            return $rule['code'];
        }
    }

    // 检查是否仅包含基础对象(不包含任何规则里的子串)
    $allSubstrings = [];
    foreach ($rules as $rule) {
        $allSubstrings = array_merge($allSubstrings, $rule['substrings']);
    }
    $allSubstrings = array_unique($allSubstrings);
    $hasAnySubstr = false;

    foreach ($allSubstrings as $substr) {
        if (strpos($string, $substr) !== false) {
            $hasAnySubstr = true;
            break;
        }
    }

    if (!$hasAnySubstr) {
        return $baseCode;
    }

    // 如果有未匹配到规则的子串,这里可以自定义返回值(比如错误码)
    return null;
}

// ------------------------------
// 针对balloon场景的规则配置
// ------------------------------
$balloonColorRules = [
    ['substrings' => ['red', 'blue', 'green'], 'code' => 11],
    ['substrings' => ['red', 'blue'], 'code' => 5],
    ['substrings' => ['red', 'green'], 'code' => 6],
    ['substrings' => ['blue', 'green'], 'code' => 7],
    ['substrings' => ['red'], 'code' => 2],
    ['substrings' => ['blue'], 'code' => 3],
    ['substrings' => ['green'], 'code' => 4],
];

// 使用示例
$testString1 = "red blue balloon";
echo getTargetCode($testString1, $balloonColorRules, 'balloon', 1); // 输出5

$testString2 = "balloon";
echo getTargetCode($testString2, $balloonColorRules, 'balloon', 1); // 输出1

$testString3 = "red green balloon";
echo getTargetCode($testString3, $balloonColorRules, 'balloon', 1); // 输出6

方案优势

  1. 完全可复用:比如你要处理另一个对象(比如car),只需要定义新的规则数组,调用同一个函数就行:
$carColorRules = [
    ['substrings' => ['black', 'white'], 'code' => 99],
    ['substrings' => ['black'], 'code' => 88],
    // ...其他规则
];
getTargetCode("black car", $carColorRules, 'car', 100);
  1. 扩展性极强:新增颜色或者组合时,只需要在规则数组里加一行,比如要加yellow,编码8,同时red+yellow编码12,直接加:
$balloonColorRules = [
    ['substrings' => ['red', 'blue', 'green'], 'code' => 11],
    ['substrings' => ['red', 'yellow'], 'code' => 12], // 新增组合规则
    // ...原有规则
    ['substrings' => ['yellow'], 'code' => 8], // 新增单个规则
];
  1. 逻辑清晰:规则按优先级从高到低排列,复杂组合先匹配,避免了嵌套if-else的混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 15:22:29