news 2026/8/26 8:50:34

MySQL字符串提取数字的三种生产级方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL字符串提取数字的三种生产级方案

1. 项目概述:为什么在MySQL里“从字符串里抠数字”是个高频刚需?

“MySQL 字符串中提取数字”——这行标题看着简单,但背后藏着大量真实业务场景里让人抓耳挠腮的硬需求。我做数据库开发和数据清洗十年,几乎每周都会遇到这类问题:用户注册时填了“张三138****1234”,订单号混着“ORD-2024-00789-TEST”,日志字段写着“内存使用率:72.3%(峰值)”,甚至财务系统里存着“¥1,234,567.89(含税)”。这些都不是标准数值字段,而是带干扰字符的混合文本,但下游报表、风控模型、BI看板却要拿里面的纯数字做计算、排序、聚合。这时候,你不能靠CAST()CONVERT()硬转——它们一碰到非数字字符就直接报错或截断为0,结果全错。

核心关键词“MySQL”“字符串”“数字”“提取”四个词叠加,指向一个明确动作:在不改变原表结构、不依赖应用层预处理的前提下,仅用SQL原生能力,从TEXT/VARCHAR字段中稳定、可复用、可预测地剥离出连续或离散的数字片段。它不是炫技,而是生产环境里的生存技能。比如电商后台要统计“优惠券码含数字位数分布”,客服系统要自动识别“用户留言中的手机号段”,或者审计系统需从操作日志中提取“执行耗时毫秒值”。这些场景共同特点是:数据已入库、字段类型不可改、ETL链路不允许加中间清洗节点、且必须单条SQL搞定。

我见过太多人第一反应是写存储过程或调用UDF(用户自定义函数),但实际一上线就踩坑:UDF需要编译安装、权限审批复杂、跨版本兼容性差;存储过程调试成本高、难以嵌入现有查询。而真正高效的做法,是吃透MySQL内置函数的组合逻辑——用REGEXP_REPLACE做“减法式清洗”,用SUBSTRING_INDEX做“分段定位”,用递归CTE(8.0+)做“多数字遍历”,甚至用JSON_TABLE(8.0.4+)把字符串当JSON数组解析。这不是堆砌函数,而是像搭积木一样理解每个函数的边界:REGEXP_REPLACE能删不能提,LOCATE能找不能切,SUBSTRING要坐标得自己算……这些细节,决定了你是写出能跑通的SQL,还是写出能扛住百万级数据、零误差的生产级SQL。

2. 核心思路拆解:三种主流方案的适用边界与底层逻辑

面对“字符串提数字”,业内常归纳为三类技术路径:正则清洗法、位置定位法、递归遍历法。很多人直接抄网上代码,但没搞清每种方法的“设计契约”——它承诺什么,又隐含什么限制。我按实际压测数据和线上故障记录,给你拆解清楚。

2.1 正则清洗法:用“删除非数字”实现最简提取(适合单数字场景)

这是新手最容易上手的方案,核心逻辑是:把所有非数字字符(包括小数点、负号、逗号等)全部替换为空,再转成数值。典型写法:

SELECT CAST(REGEXP_REPLACE('价格:¥1,234.56(含税)', '[^0-9.]', '') AS DECIMAL(10,2)) AS price; -- 结果:1234.56

表面看很优雅,但陷阱藏在正则表达式[^0-9.]里。^表示“非”,[0-9.]匹配数字和小数点,所以它删掉的是“除数字和小数点外的所有字符”。这里的关键认知是:正则清洗本质是“保留下标集”,而非“提取子串”。它不关心数字在原字符串中的位置、个数、是否连续,只做全局字符过滤。因此它天然适合“单值提取”场景——比如从地址字段“北京市朝阳区建国路8号SOHO现代城A座1201室”中提取门牌号“1201”,因为门牌号通常是唯一连续数字块。

但一旦遇到多数字混合,问题就来了。例如字段值为“订单ID:ORD-2024-00789,创建时间:2024-03-15”,用REGEXP_REPLACE(..., '[^0-9]', '')会得到“20240078920240315”,把年份、订单号、日期全揉成一团。这时候你得追问:业务到底要哪个数字?是取第一个出现的(2024),还是最长的(202400789),或是带前导零的(00789)?正则清洗法无法回答,因为它丢失了所有位置信息。我的经验是:只要业务需求明确“只取一个数字”,且该数字在字符串中语义唯一(如身份证号、手机号、商品编码),正则清洗法就是最优解——代码短、性能稳、兼容性好(5.7+全支持)

2.2 位置定位法:用“找-切-转”三步法精准捕获指定数字(适合结构化文本)

当字符串有固定模式,比如“用户ID:U12345,等级:VIP3,积分:9876”,你需要分别提取12345、3、9876三个值,正则清洗就失效了。这时必须回归SQL最基础的能力:基于分隔符的位置计算。MySQL没有SPLIT函数,但SUBSTRING_INDEX是神队友。它的语法是SUBSTRING_INDEX(str, delim, count),意思是“取str中第count个delim之前(或之后)的部分”。

我们以提取“等级:VIP3”中的“3”为例:

-- 先用空格分割,取第三段("等级:VIP3,积分:9876") SET @segment = SUBSTRING_INDEX(SUBSTRING_INDEX('用户ID:U12345,等级:VIP3,积分:9876', ',', 2), ',', -1); -- 得到"等级:VIP3" -- 再用":"分割,取第二段 SELECT CAST(SUBSTRING_INDEX(@segment, ':', -1) AS UNSIGNED) AS level; -- 得到3

这个方案的核心是把字符串当作结构化数据来解析。它要求你提前知道分隔符(中文顿号“、”、英文逗号“,”、冒号“:”等)和目标数字的相对位置。优势在于:结果绝对可控,不会因正则误匹配而错乱;支持前导零保留(用SUBSTRING代替CAST);5.7+全版本可用。我在某银行反洗钱系统里就用这套逻辑解析交易备注:“收款方:张*,账号:6228****1234,金额:¥5,000.00”,通过两次SUBSTRING_INDEX精准定位到“5,000.00”,再用REPLACE去掉逗号,最后CAST成DECIMAL。

但它的硬伤是脆弱性——一旦源字符串格式微调(比如把“,”换成“;”,或漏掉空格),整个链路就崩。所以我在生产环境必加“容错兜底”:用CASE WHEN ... REGEXP '等级:VIP[0-9]+' THEN ... ELSE NULL END先校验格式,再执行定位。这增加了10%代码量,却避免了90%的线上事故。

2.3 递归遍历法:用CTE逐个扫描提取所有数字(适合无规律文本)

最棘手的场景是:日志字段“Error 404 at /api/v1/user/123 not found, retry after 30s, timeout=5000ms”,里面混着状态码404、用户ID123、重试间隔30、超时5000——四个数字,位置随机,长度不一,且可能有负数、小数。正则清洗会拼成“404123305000”,位置法定位不了。这时就得上MySQL 8.0+的杀手锏:递归公用表表达式(Recursive CTE)

原理很简单:把字符串想象成一条线,从左到右逐个字符检查,遇到数字就记下起始位置,直到非数字为止,形成一个“数字块”,然后跳到下一个字符继续。CTE的递归部分负责“移动指针”,非递归部分负责“初始化”。实操代码如下:

WITH RECURSIVE digit_extractor AS ( -- 初始:从位置1开始,设当前字符索引为1,暂存数字串为空 SELECT 'Error 404 at /api/v1/user/123 not found' AS str, 1 AS pos, '' AS current_num, '' AS result UNION ALL -- 递归:检查pos位置字符 SELECT str, pos + 1, CASE WHEN SUBSTRING(str, pos, 1) REGEXP '^[0-9]$' THEN CONCAT(current_num, SUBSTRING(str, pos, 1)) ELSE '' END, CASE WHEN SUBSTRING(str, pos, 1) REGEXP '^[0-9]$' AND (pos = LENGTH(str) OR SUBSTRING(str, pos + 1, 1) NOT REGEXP '^[0-9]$') THEN CONCAT(result, IF(current_num != '', CONCAT(',', current_num), '')) ELSE result END FROM digit_extractor WHERE pos <= LENGTH(str) ) SELECT TRIM(BOTH ',' FROM result) AS all_numbers FROM digit_extractor WHERE pos > LENGTH(str); -- 结果:404,123,30,5000

这段代码的精妙在于状态机设计current_num缓存正在构建的数字,result累积已提取的数字,pos是游标。关键判断是SUBSTRING(str, pos, 1) NOT REGEXP '^[0-9]$'——只有当当前字符是数字且下一个字符不是数字(或已是末尾)时,才把current_num追加到result。这确保了“404”“123”被完整捕获,而不是拆成“4”“0”“4”。

但必须强调:递归CTE是CPU密集型操作,对长字符串(>1KB)或大数据量(>10万行)会显著拖慢查询。我在某运营商日志分析项目中实测:10万行日志,平均字符串长度200字符,递归CTE耗时1.8秒/行,而正则清洗法仅0.02秒/行。所以我的铁律是:只在“必须提取全部数字”且“数据量可控”时启用递归方案,并强制加WHERE条件缩小范围。比如先用WHERE log_content REGEXP '[0-9]{2,}'过滤出含至少2位数字的记录,再对这部分执行CTE。

3. 实操细节与参数精调:从函数选型到性能压测的全链路验证

光知道三种方案还不够,真实落地时,每个函数的参数选择、边界处理、性能阈值都决定成败。下面我把十年踩过的坑,浓缩成可直接抄作业的实操清单。

3.1 REGEXP_REPLACE的正则表达式:别再用[^0-9]这种危险写法

网上90%的教程教用REGEXP_REPLACE(str, '[^0-9]', ''),看似简洁,实则埋雷。问题出在[^0-9]的字符集覆盖太宽——它会删掉所有非ASCII数字字符,包括中文数字“一、二、三”,但更致命的是:它会把小数点.也删掉,导致“123.45”变成“12345”。而业务中价格、评分、坐标等小数极其常见。

正确做法是显式声明保留字符集。根据业务需求分三档:

  • 只要整数REGEXP_REPLACE(str, '[^0-9]', '')—— 简单粗暴,适合手机号、ID类。
  • 要保留小数点(且保证最多一个)REGEXP_REPLACE(str, '[^0-9.]', '')—— 但需后续校验小数点个数,防“123.45.67”变“123.45.67”。
  • 要智能保留小数点+负号(科学计数法)REGEXP_REPLACE(str, '([^0-9.-]|(?<!^)-(?![0-9])|\\.(?![0-9])|-(?![0-9.])|\\.(?=[^0-9]*$))', '')—— 这个正则够用,解释下:(?<!^)-(?![0-9])排除开头的负号(如“-123”要保留),\\.(?![0-9])排除后面没数字的小数点(如“123.”),-(?![0-9.])排除后面跟非数字的负号。

我在线上环境强制要求:所有正则清洗必须配CAST(... AS DECIMAL(m,n)),且m,n按业务最大值设(如金额设DECIMAL(15,2)),避免隐式转换溢出。曾有个项目把CAST('999999999999999' AS SIGNED)写成INT,结果超限变-1,引发资损。

3.2 SUBSTRING_INDEX的嵌套深度:别超过5层,否则维护性归零

位置定位法依赖SUBSTRING_INDEX嵌套,但嵌套过深会变成“俄罗斯套娃”。比如解析“a:b:c:d:e:f:g:h:i:j”取第7段,写SUBSTRING_INDEX(SUBSTRING_INDEX(...,':',7),':',-1),代码可读性极差。我的经验是:嵌套不超过3层,超3层必须拆成变量或临时表

更优解是用动态位置计算。例如提取“路径:/user/123/profile/edit”中的用户ID“123”,不要写:

-- ❌ 嵌套4层,难读难改 SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(path, '/', 3), '/', -1), '/', 1)

而是:

-- ✅ 用LOCATE找第2个/和第3个/的位置,直接SUBSTRING SET @path = '/user/123/profile/edit'; SET @pos1 = LOCATE('/', @path, 2); -- 第2个/位置 SET @pos2 = LOCATE('/', @path, @pos1 + 1); -- 第3个/位置 SELECT SUBSTRING(@path, @pos1 + 1, @pos2 - @pos1 - 1) AS user_id; -- 结果:123

LOCATE(str, substr, [start])返回子串首次出现位置,start参数让定位可编程。这样写虽然多两行,但逻辑清晰:第2个/后到第3个/前就是ID。我在某SaaS平台URL路由解析模块就用此法,把10+种路径模板统一成位置计算,维护成本降了70%。

3.3 递归CTE的性能红线:字符串长度超500字符必须加前置过滤

递归CTE的性能瓶颈在字符串长度。MySQL递归默认最大深度1000,但实际受cte_max_recursion_depth变量控制(默认1000)。当字符串含大量非数字字符时,递归次数=字符串长度,很容易触顶。比如10KB日志,递归1万次,直接OOM。

我的压测结论(i7-10875K, 32GB RAM, MySQL 8.0.32):

字符串长度行数平均耗时是否触发警告
<100字符10万0.05秒
100-500字符10万0.3秒
>500字符1万1.2秒是(Warning 3636)

解决方案是双保险

  1. 前置WHERE过滤WHERE LENGTH(log_text) <= 500 AND log_text REGEXP '[0-9]',先筛掉超长和无数字的行。
  2. 递归深度限流:在CTE中加WHERE pos <= 500,强制截断,避免无限递归。

另外,结果去重和排序必须放在CTE外部。CTE内部做ORDER BY会极大拖慢,因为每次递归都要排序。正确写法:

WITH RECURSIVE extractor AS (...) SELECT DISTINCT CAST(num AS UNSIGNED) AS number FROM (SELECT TRIM(BOTH ',' FROM result) AS num FROM extractor WHERE pos > LENGTH(str)) t ORDER BY number;

3.4 兼容性兜底方案:MySQL 5.7如何实现“类CTE”效果

很多老系统还在用MySQL 5.7,不支持递归CTE。别慌,用辅助数字表(Numbers Table)模拟。原理是:建一张只有数字1到1000的表,用JOIN代替递归,对每个位置做SUBSTRING检查。

建表语句:

CREATE TABLE numbers (n INT PRIMARY KEY); INSERT INTO numbers VALUES (1),(2),(3),...,(1000); -- 用脚本生成

提取逻辑:

SELECT GROUP_CONCAT( DISTINCT CASE WHEN SUBSTRING('Error 404 at 123', n, 1) REGEXP '^[0-9]$' AND (n = 1 OR SUBSTRING('Error 404 at 123', n-1, 1) NOT REGEXP '^[0-9]$') THEN SUBSTRING('Error 404 at 123', n, LEAST( LENGTH('Error 404 at 123') - n + 1, COALESCE(NULLIF(LOCATE(' ', CONCAT(SUBSTRING('Error 404 at 123', n), ' '), ' '), 1) - 1, 0), COALESCE(NULLIF(LOCATE(',', CONCAT(SUBSTRING('Error 404 at 123', n), ','), ','), 1) - 1, 0) ) ) END SEPARATOR ',' ) AS numbers FROM numbers WHERE n <= LENGTH('Error 404 at 123');

虽然代码长,但它在5.7上稳定运行,且性能比模拟递归好——因为JOIN是MySQL优化器最擅长的。我在某政府旧系统迁移项目中,用此法替代了原PHP层的循环解析,查询速度从8秒降到0.3秒。

4. 常见问题与排查技巧实录:从报错信息到执行计划的全维度诊断

再完美的方案,上线也会遇到各种“意料之外”。我把近五年处理过的典型问题,按发生频率排序,附上根因分析和一键修复命令。

4.1 错误1064:REGEXP_REPLACE在5.7报错,但文档说支持?

现象:执行SELECT REGEXP_REPLACE('abc123', '[^0-9]', '');报错ERROR 1064 (42000): You have an error in your SQL syntax

根因REGEXP_REPLACE是MySQL 8.0.4引入的函数,5.7确实不支持!网上很多教程没标注版本,导致新手踩坑。5.7只能用REPLACE函数做简单替换,但REPLACE不支持正则,无法处理“删所有非数字”。

修复方案

  • 升级到8.0+(推荐);
  • 或用ELT+FIND_IN_SET模拟(仅限少量固定字符);
  • 最稳妥是应用层处理:查出字符串,在Java/Python里用正则清洗,再回写。我在某金融项目中,因升级窗口受限,就用Python的re.sub(r'[^0-9.]', '', s)批量处理,速度比SQL快3倍。

4.2 提取结果为NULL:CAST失败却不报错?

现象SELECT CAST('abc' AS UNSIGNED)返回0,而非报错;SELECT CAST('123abc' AS UNSIGNED)也返回123,但业务需要严格校验。

根因:MySQL的CAST有“静默截断”特性——遇到非数字开头,返回0;遇到数字开头后接非数字,只取前面数字部分。这违反了数据完整性原则。

修复方案STRCMP+REGEXP双重校验

SELECT CASE WHEN str REGEXP '^[0-9]+$' THEN CAST(str AS UNSIGNED) WHEN str REGEXP '^[0-9]+\\.[0-9]+$' THEN CAST(str AS DECIMAL(10,2)) ELSE NULL END AS safe_number FROM table;

^[0-9]+$确保纯整数,^[0-9]+\.[0-9]+$确保标准小数。这样NULL值可被下游程序捕获并告警,而不是悄悄变成0引发计算错误。

4.3 性能骤降:加了REGEXP_REPLACE后查询从0.1秒变5秒?

现象:原本很快的查询,加上REGEXP_REPLACE字段后,执行时间暴涨,EXPLAIN显示type: ALL(全表扫描)。

根因REGEXP_REPLACE是计算型函数,无法利用索引。如果WHERE条件里用了它,比如WHERE REGEXP_REPLACE(name, '[^0-9]', '') = '123',MySQL必须对每行计算后再比较,彻底放弃索引。

修复方案把计算逻辑移到应用层或加生成列

  • 方案1(推荐):在应用层清洗后,存一个clean_number字段,对该字段建索引。
  • 方案2(8.0+):用生成列(Generated Column)自动计算:
    ALTER TABLE orders ADD COLUMN order_id_clean VARCHAR(20) GENERATED ALWAYS AS (REGEXP_REPLACE(order_id, '[^0-9]', '')) STORED, ADD INDEX idx_clean_id (order_id_clean);
    这样WHERE order_id_clean = '123'就能走索引,查询回到0.1秒。

4.4 多数字提取错乱:递归CTE返回重复或遗漏?

现象:对字符串“a1b2c3”执行递归CTE,结果是“1,2,3,2,3”,数字重复。

根因:CTE递归时,WHERE pos <= LENGTH(str)条件没写在递归分支里,导致非递归部分被多次执行。标准写法必须确保递归分支有独立WHERE。

修复方案:严格按官方CTE语法,递归部分必须用UNION ALL连接,且递归查询的WHERE必须限定pos

WITH RECURSIVE cte AS ( SELECT 1 as pos, '' as num, '' as res UNION ALL SELECT pos + 1, CASE WHEN SUBSTRING('a1b2c3', pos+1, 1) REGEXP '[0-9]' THEN ... END, ... FROM cte WHERE pos < LENGTH('a1b2c3') -- ✅ 关键:WHERE必须在这里 ) SELECT ... FROM cte WHERE pos = LENGTH('a1b2c3') + 1;

4.5 中文字符乱码:SUBSTRING_INDEX切出“?”而非汉字?

现象:字符串字段是utf8mb4,但SUBSTRING_INDEX('用户:张三', ':', -1)返回“?”。

根因:MySQL的SUBSTRING_INDEX按字节计算,而utf8mb4中文占3-4字节。当分隔符“:”是全角字符(Unicode U+FF1A),其字节序列与半角“:”不同,SUBSTRING_INDEX可能切在中文字符中间,造成乱码。

修复方案统一用CONVERT转二进制再操作

SELECT CONVERT(SUBSTRING_INDEX(CONVERT('用户:张三' USING utf8mb4), CONVERT(':' USING utf8mb4), -1) USING utf8mb4);

或者更简单:在应用层确保分隔符统一,比如约定所有分隔符用半角符号,避免混用全角/半角。

5. 高阶技巧与生产级实践:从单表查询到ETL流水线的工程化落地

以上都是单点技术,但真实项目需要体系化。我把多年沉淀的工程化方法论,浓缩成三条铁律。

5.1 铁律一:永远先做“数据探查”,再写SQL

别急着写REGEXP_REPLACE。先执行:

-- 查看字符串分布 SELECT LENGTH(content) as len, content REGEXP '[0-9]' as has_digit, content REGEXP '[^0-9]' as has_non_digit, COUNT(*) as cnt FROM logs GROUP BY len > 100, has_digit, has_non_digit ORDER BY cnt DESC;

这能快速发现:80%的字符串长度<50,且都含数字;但有5%的字符串长度>1000,且含大量特殊符号。这时你就知道:主流程用正则清洗,那5%的脏数据单独走递归CTE+限流,避免拖垮整体。

我在某电商大促日志分析中,用此法发现0.3%的日志含base64编码,直接过滤掉,查询提速40%。

5.2 铁律二:用生成列固化提取逻辑,避免重复计算

每次查询都执行REGEXP_REPLACE,CPU白白浪费。8.0+的生成列是救星:

ALTER TABLE user_profiles ADD COLUMN phone_clean CHAR(11) GENERATED ALWAYS AS (REGEXP_REPLACE(phone, '[^0-9]', '')) STORED, ADD CONSTRAINT chk_phone_len CHECK (LENGTH(phone_clean) = 11);

STORED表示物理存储,查询时直接读,不计算。CHECK约束确保清洗后长度合规。这样SELECT * FROM user_profiles WHERE phone_clean = '13812345678'走索引,且数据质量有保障。

5.3 铁律三:建立“提取规则库”,用JSON配置驱动

不同业务线提取规则不同:客服要手机号,风控要IP,BI要金额。硬编码SQL维护成本高。我的方案是建规则表:

CREATE TABLE extraction_rules ( rule_id INT PRIMARY KEY, field_name VARCHAR(50), pattern VARCHAR(100), -- 正则模式 data_type ENUM('INT','DECIMAL','STRING'), is_active TINYINT ); INSERT INTO extraction_rules VALUES (1, 'log_content', 'Error ([0-9]+)', 'INT'), (2, 'remark', '金额:¥([0-9.]+)', 'DECIMAL');

然后用动态SQL或应用层解析规则,生成对应查询。这样新增一个提取需求,只需插一行配置,不用改代码。

最后分享个小技巧:在MySQL Workbench里,把常用提取SQL存成代码片段(Snippets)。比如REGEXP_REPLACE模板、位置定位模板、CTE模板,输入快捷键就能调出,写SQL效率翻倍。我自己的Snippet库里有12个提取相关模板,每天节省至少20分钟。

我在实际使用中发现,最省心的方案不是最炫的,而是最贴合业务语义的。比如提取订单号,如果业务约定“订单号以ORD-开头,后跟6位数字”,那就别用正则,直接SUBSTRING(content, 5, 6),又快又准。技术是手段,解决业务问题才是目的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/26 8:47:32

算法刷题笔记:从模式识别到面试实战

1. 刷题笔记的价值与定位 每次打开LeetCode或者牛客网&#xff0c;看到那些AC通过的绿色标记时&#xff0c;我都能回想起刚开始刷题时的手足无措。这份2026年初的刷题笔记&#xff0c;记录了我从算法小白到能够独立解决中等难度题目的完整心路历程。不同于普通的题解合集&#…

作者头像 李华
网站建设 2026/8/26 8:47:21

基于OpenClaw构建个人自动化助手:从任务调度到智能监控的完整实践

1. 项目缘起&#xff1a;从“手动挡”到“自动巡航”的转变作为一名常年与代码和数据打交道的从业者&#xff0c;我每天的工作流里充斥着大量重复、琐碎但又不得不做的“体力活”。比如&#xff0c;每天上班第一件事&#xff0c;打开十几个网页查看项目状态、监控数据面板&…

作者头像 李华
网站建设 2026/8/26 8:46:52

嵌入式工程师必懂:JTAG调试接口原理、排查技巧与安全禁用

做嵌入式这些年&#xff0c;我越来越觉得JTAG像一门语言&#xff1a;每一块芯片都在讲它&#xff0c;调试器也在讲它&#xff0c;但真正能流利“说”JATG的工程师&#xff0c;并没有想象中那么多。很多次被人拉去救火&#xff0c;现象无非是调试器连不上、程序烧不进去、板子变…

作者头像 李华
网站建设 2026/8/26 8:44:40

AI项目避坑指南:七类不适合AI的场景与评估方法

1. 从“AI焦虑”到“AI冷静”&#xff1a;为什么有些项目天生不适合AI&#xff1f;最近和几个不同行业的朋友聊天&#xff0c;发现一个挺有意思的现象&#xff1a;大家嘴上都在谈AI转型&#xff0c;但真正聊到具体项目时&#xff0c;不少人脸上都挂着一种“为了AI而AI”的迷茫。…

作者头像 李华
网站建设 2026/8/26 8:42:57

Small-Scale生命游戏实战:从规则解析到Python实现与坑点总结

1. 项目概述&#xff1a;为什么做一个“Small-Scale”版生命游戏康威生命游戏&#xff08;Game of Life&#xff09;可以说是几乎所有程序员的第一个“非业务型”项目。它不涉及登录注册、不涉及增删改查&#xff0c;纯粹是一个从简单规则演化出复杂行为的模拟系统。我在不同阶…

作者头像 李华