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

Python含数字驼峰转大写蛇形的正则表达式问题排查

驼峰转大写蛇形命名的正则问题分析

问题场景

编写了Python方法通过正则将驼峰式字符串转为大写蛇形命名(screaming snake case),要求在大小写变化处、非数字与数字字符之间插入下划线,但测试出现不符合预期的结果:

  • 输入vn3b返回VN3B,预期为VN_3_B
  • 输入vnRbb250V返回VN_RBB_250V,预期为VN_RBB_250_V

原实现代码:

import re

def camel_to_screaming_snake(value):
    return '_'.join(re.findall('[A-Z][a-z]+|[0-9A-Z]+(?=[A-Z][a-z])|[0-9A-Z]{2,}|[a-z0-9]{2,}|[a-zA-Z0-9]'
                                        , value)).upper()

正则表达式的核心问题

当前正则的分支匹配逻辑存在三个关键缺陷:

  1. 分支优先级导致范围过度匹配:正则分支按顺序匹配,[a-z0-9]{2,}会把连续的小写字母+数字(比如vn3)整体匹配,不会拆分为vn和3;同理[0-9A-Z]{2,}会把250V整体匹配,使得数字和后面的大写字母无法拆分。
  2. 未明确区分数字与字母的边界:原正则没有单独处理数字与字母相邻的场景,无法在两者之间插入下划线。
  3. 末尾单个大写字母的匹配遗漏:字符串末尾的单个大写字母(比如vnRbb250V中的V)会被前面的[0-9A-Z]{2,}分支包含,导致无法单独拆分出来。

修正方案

方案一:分步插入下划线(逻辑更清晰)

换一种思路,先在需要拆分的位置插入下划线,再统一转大写:

import re

def camel_to_screaming_snake(value):
    # 小写转大写的位置前插入下划线
    temp = re.sub(r'([a-z])([A-Z])', r'\1_\2', value)
    # 非数字与数字相邻处插入下划线
    temp = re.sub(r'([^\d])(\d)', r'\1_\2', temp)
    # 数字与非数字相邻处插入下划线
    temp = re.sub(r'(\d)([^\d])', r'\1_\2', temp)
    # 转为大写
    return temp.upper()

测试验证:

  • 输入vn3b → 输出VN_3_B
  • 输入vnRbb250V → 输出VN_RBB_250_V

方案二:调整正则分支(基于findall实现)

重新设计正则分支,确保每个需要拆分的单元被单独匹配:

import re

def camel_to_screaming_snake(value):
    return '_'.join(re.findall(
        r'[A-Z][a-z]+|\d+|[A-Z]|[a-z]+',
        value
    )).upper()

分支逻辑说明:

  • [A-Z][a-z]+:匹配大写开头后跟连续小写的组合(如Rbb)
  • \d+:匹配连续数字(如250)
  • [A-Z]:匹配单个大写字母(如V)
  • [a-z]+:匹配连续小写字母(如vn)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:30:43