Skip to content
返回博客
教程

camelCase vs snake_case vs kebab-case 命名约定完全指南 2026

camelCase vs snake_case vs kebab-case 命名约定 2026 — 6 种 case 风格 + 7 大语言决策矩阵 + 缩写规则 + URL SEO + 6 大转换陷阱。

14 分钟阅读

camelCase vs snake_case vs kebab-case 命名约定完全指南 2026

userID 还是 userIduser_profile 还是 userProfile?URL 用 - 还是 _?这些问题在 PR review 里被反复争论,但答案并不取决于个人偏好——每种主流语言、每条 Web 标准都有定型的规则。

本文覆盖代码里会遇到的 6 种 case(camelCase、PascalCase、snake_case、kebab-case、CONSTANT_CASE、dot.case / path/case / Header-Case)、一份 7 语言决策矩阵、带 GitHub 数据的 parseUrl-vs-parseURL 缩写之争、kebab-case URL 的 SEO 理由,以及自动转换时常见的 6 个坑。需要看任意字符串在 15 种 case 下的输出,大小写转换工具能在浏览器里实时渲染。

6 种 case 一张速查

先把速查表放在最前面,方便对照。

Case 风格示例典型用途起源 / 推广者
camelCaseuserProfileImageJS、TS、Java、Swift 的变量与方法Smalltalk → Java
PascalCaseUserProfileImage类、React/Vue 组件、TS 类型Pascal 语言
snake_caseuser_profile_imagePython、Ruby、Rust、SQL 列名C / 早期 Unix
kebab-caseuser-profile-imageCSS 类名、URL slug、HTML 属性Lisp / 现代 Web
CONSTANT_CASEUSER_PROFILE_IMAGE环境变量、顶层常量、宏C 宏 / Unix 环境
dot.caseuser.profile.imageJava 包、MongoDB 路径、TOML 键命名空间约定
path/caseuser/profile/imageURL 路径、文件系统、Git 引用Unix 路径
Header-CaseUser-Profile-ImageHTTP/1.1 头部名(canonical 写法)RFC 2616

表里 8 行对应 6 种实质不同的 case。dot.case、path/case、Header-Case 共用同一套分词规则,只是分隔符不同,大多数 case 库会把它们归为同一家族。

每种 case 的细节

camelCase:JS/Java 的默认

camelCase 由 Smalltalk 提出,Java 把它推向了全行业。Sun 1995 年的 Java 编码规范把 firstNamegetUserProfilexmlParser 钉为默认写法,此后追随 Java 风格的语言(JavaScript、ActionScript、Swift、Kotlin、Dart)都继承了同一形态。

规则:首词全小写,后续每个单词首字母大写,分隔符全部去掉。没有下划线,没有连字符,没有空格。名字源自大写字母在小写中凸起的驼峰外形。

两个常出错的边缘情况。一是品牌名里以小写起首的词(iPhoneeBayiOS),出现在代码里时按品牌原写法保留,不要强行把 i 大写。二是缩写,下面会专门讨论。

PascalCase:类与组件

PascalCase 是首字母大写版的 camelCase。有些风格指南叫它「UpperCamelCase」。Pascal 语言 1970 年代就在用,名字由此而来。

适用范围:所有 C 系 OO 语言的类名(Java、C#、C++、Kotlin、Swift、TypeScript)、React/Vue/Angular 的组件名、TypeScript 的类型别名与接口(type UserProfileinterface AuthState),以及某些生态里的模块/文件名(C# 的 UserService.cs)。

为什么要单独给类一种 case?为的是视觉信号。new userProfile()new UserProfile() 摆在一起,后者一眼就是类型。在值与类型共享命名空间的语言里,大小写承担了消歧的工作。

snake_case:Python、Ruby、Rust、SQL

snake_case 比一般印象更古老。C 和早期 Unix 就在用 errno_hfopen_s 这类名字,PDP-11 终端键盘按下划线方便,而 Pascal 那种大小写来回切的写法很费劲。Python 把它写进 PEP 8 作为官方约定;Ruby 社区自发收敛到 snake_case;Rust 把它做成编译器强制的默认,写成 userId 而不是 user_id,lint 立刻报错。

规则:全小写,单词之间用下划线连接。user_profile_imageparse_htmlmax_retries

数据库这一面很关键,多数语言教程会跳过。几乎所有 SQL ORM(SQLAlchemy、Hibernate、Sequelize、TypeORM、Active Record)默认都用 snake_case 列名,不管宿主语言的约定是什么。原因是可移植性:PostgreSQL 把未加引号的标识符折叠成小写,MySQL 在 Linux 上区分大小写、在 macOS/Windows 上不区分,SQLite 把列名当成不透明字符串。snake_case 是唯一不加引号就能在所有数据库里行为一致的写法。

kebab-case:Web 的选择

Web 在所有用户可见的地方都汇聚到了 kebab-case:CSS 类名(.user-profile-image)、URL slug(/blog/naming-conventions-guide)、HTML 自定义属性(data-user-id)、Web Component 标签名(<user-card>,规范要求里面必须含连字符)。

这个名字在旧文档里有过多种叫法:「dash-case」「spinal-case」「lisp-case」「skewer-case」「hyphen-case」。指的都是同一种东西,「kebab-case」是后来通用的名字。

一个不显眼的规则:HTML 和 CSS 的类名行为上不区分大小写,但 canonical 写法是全小写。.User-Profile 在大多数浏览器里能用,但会让对类名做哈希的服务端工具出问题。坚持全小写就对了。

CONSTANT_CASE:环境变量与宏

CONSTANT_CASE(Rust 圈子里有时叫 SCREAMING_SNAKE_CASE)是「这个值在运行时永远不变」的通用信号。MAX_RETRIESAPI_KEYDEFAULT_TIMEOUT_MS。各语言都有对应约定;CI 系统、容器运行时、shell 都期望环境变量是这种写法(DATABASE_URLNODE_ENVPATH)。

陷阱:JavaScript 的 const 关键字并不意味着「该用 CONSTANT_CASE」。const result = await fetch(url) 是正确的 camelCase。CONSTANT_CASE 留给语义上的常量——在 C 里会用 #define 写出来的那种、运行时改值就是 bug 的东西。MAX_RETRIES = 3 符合标准,result 不符合。

dot.case、path/case、Header-Case

三种共享同一分词逻辑、仅分隔符不同的变体。

dot.case 表达层级键:Java 包名(com.example.service)、MongoDB 字段路径(user.profile.image)、TOML/INI 配置键([database.primary])、Lodash 方法路径(_.get(obj, 'user.profile.image'))。一个 dot.case 字符串读出来的结构是「命名空间,命名空间,叶子」。

path/case 表达真实位置:URL 路径、文件系统路径、Git 引用(feature/add-auth)。点和斜杠的选择是有意义的:斜杠表示某处真实存在的东西,点表示一个标签。

Header-Case 是 HTTP/1.1 的约定:Content-TypeAccess-Control-Allow-OriginX-Forwarded-For。HTTP/1.1 头部在协议层不区分大小写(RFC 2616),content-type 也能工作,但框架、文档和开发者习惯都期望 Header-Case 写法。HTTP/2 和 HTTP/3 改变了这一点:RFC 7540 §8.1.2 强制要求在线传输的头部名全小写,目的是简化头部压缩(HPACK)。这对应用代码是透明的,HTTP/2 客户端和服务器会自动归一化;如果直接抓一个 HTTP/2 帧,里面的头部是全小写的 kebab-case。

7 语言决策矩阵

平息命名争论最快的办法,是去看这门语言的标准库怎么写。矩阵如下。

语言变量函数常量文件名DB 列名
Python (PEP 8)snake_casesnake_casePascalCaseCONSTANT_CASEsnake_case.pysnake_case
JavaScript/TScamelCasecamelCasePascalCaseCONSTANT_CASEkebab-case.jssnake_case
GocamelCase*PascalCase**PascalCasemixedCase***snake_case.gosnake_case
Rustsnake_casesnake_casePascalCaseSCREAMING_SNAKEsnake_case.rssnake_case
JavacamelCasecamelCasePascalCaseCONSTANT_CASEPascalCase.javasnake_case
C#camelCase†PascalCasePascalCasePascalCasePascalCase.cssnake_case
SQLn/asnake_casen/an/an/asnake_case
  • * Go:首字母小写表示未导出(包级私有),首字母大写表示导出(公开)。编译器强制这一约定。
  • ** Go:导出函数用 PascalCase(http.NewRequest),包级私有函数用 camelCase(http.parseHeader)。
  • *** Go:常量遵循同样的导出/未导出规则——导出常量写作 MaxRetries,未导出写作 maxRetries。Go 刻意避开了 CONSTANT_CASE。
  • C#:局部变量和私有字段是 camelCase(部分代码库会给字段加 _ 前缀:_userName);公开属性、方法、类型是 PascalCase。

三个跨语言、横切所有栈的层:

HTML 与 CSS:类名和 ID 是 kebab-case(<div class="user-profile-card">)。HTML 自定义属性是带 data- 前缀的 kebab-case(data-user-id)。内联 CSS 属性是 kebab-case(background-color);对应的 JS DOM 写法是 camelCase(element.style.backgroundColor)。

HTTP:在 HTTP/1.1 上发出的头部名是 Header-Case('Content-Type': 'application/json'),在 HTTP/2 在线传输时是小写 kebab-case。大多数 fetch 库都能接受任一写法,内部会自动归一化。

环境变量:全部 CONSTANT_CASE——Node、Python、Go、Rust、Bash、Docker、Kubernetes 一视同仁。.env 文件也是同样的约定:DATABASE_URL=postgres://...

缩写处理:Google vs Microsoft

这是 code review 里争议最大的命名问题。该写 parseUrl 还是 parseURLuserId 还是 userIDHtmlParser 还是 HTMLParserXmlHttpRequest 还是 XMLHttpRequest

有两套流派,背后都有权威背书。

把缩写当作普通词(Google、Apple、现代 JS)parseUrluserIdHtmlParser。Google JavaScript Style Guide §5.3 明文推荐,Apple Swift API Design Guidelines 同样如此。lodash 和 change-case 包默认产出这种写法。核心理由是往返稳定性:parseUrl 能干净地分词为 parse / url,转成 parse_url,再转回 parseUrl,信息无损。parseURL 被分词为 parse / URL,朴素分词器输出 parse_u_r_l,缩写感知的分词器输出 parse_url;但 parse_url 无法判断该回到 parseUrl 还是 parseURL,全小写写法把缩写信号弄丢了。

保留缩写大写(Microsoft、.NET、老式 Java)parseURLuserIDHTMLParserXMLHttpRequest。Microsoft .NET Naming Guidelines 把这条规则限制在 2-3 字母的缩写(IOURLXML),更长的缩写按普通词处理(按严格规则 Html 该保留大写,但 Microsoft 实际写的是 HtmlAgilityPack)。Win32 API、.NET BCL 以及 2010 年以前的大多数 Java 代码都用这种风格。它对英语读者更直观(parseURL 看上去就是「parse U-R-L」),代价是失去往返性。

Python 的 PEP 8 名义上推荐当作普通词,但标准库历史上并不一致:http.server.HTTPServerxml.etree.ElementTreejson.JSONDecoder 保留了缩写大写;新近加入的 pathlib.PurePathdataclasses 倾向于当作普通词。PEP 8 的原则是跟随周围代码的风格。

2026 年初对 GitHub 公开语料的抽样(BigQuery 的 bigquery-public-data.github_repos,筛选 star 数 1k+ 仓库的 TypeScript 与 JavaScript 文件)显示 parseUrlparseURL 约为 7:3,userIduserID 约为 6:4。普通词风格在 JavaScript 里占上风。C# 仍然倾向 Microsoft 风格,parseURL 在 C# 文件里占主导。Python 大致五五开。

决策规则:(a) 跟随所写语言的标准库;(b) 标准库本身不一致时,新项目选普通词风格,因为它能往返;(c) 把决定写进 lint 配置或风格指南,单个项目内不混用。大小写转换的分词器采用普通词约定,与 lodash 和 change-case 一致:粘贴 XMLHttpRequest,会得到 xmlHttpRequestxml_http_requestxml-http-request 作为 camelCase、snake_case、kebab-case 的输出。

URL Slug:为什么 kebab-case 击败 snake_case

Google Search Central 关于 URL 结构的官方文档有一条具体的 case 建议:URL 里用连字符分隔单词,不用下划线。原因是分词。Google 搜索索引在连字符处切分 URL,不在下划线处切。https://example.com/buy-running-shoes 被分词为 buyrunningshoes 三个可索引词项,任意一词命中都算。https://example.com/buy_running_shoes 则被分词为单一词项 buy_running_shoes,只有一字不差的查询才会命中。

对排名稳定的页面,差距很小(Google 还有别的信号);对在拥挤 SERP 里争位置的新页面,差距真实存在。同等条件下,kebab-case URL 排名更高。

第二个原因是大小写敏感性。URL 路径在 Linux 服务器上区分大小写(也就是绝大多数 Web 环境)。/User-Profile/user-profile 是两个不同的 URL、两条不同的缓存记录、两行不同的分析数据。小写 kebab-case 是唯一不会引来跨环境 bug 的写法。

任何标题都能套用的 4 步 slug 配方:

  1. 全部小写。
  2. 把连续空白和标点替换成单个连字符。
  3. 去掉首尾的连字符。
  4. 可选:去掉停用词(aantheoffor)以缩短 URL。仅在 CMS 会保留原始标题作为页面 H1 时才这么做。

实战示例:"10 Tips for Faster JavaScript: A Complete Guide"10-tips-faster-javascript-complete-guide。冒号和停用词(fora)被剥掉;结果 39 个字符,落在 50-60 字符的 SERP 显示区间内。关于 URL 长度与各平台字符限制的互动,参考字符与字数限制完全指南

大小写转换能把任意标题一键转成 kebab-case,给 CMS 迁移或 sitemap 批量生成 slug 时很省力。

6 大转换陷阱

case 之间的自动转换看起来简单,实际并不。下面是常出问题的 6 个地方。

1. 数字与字母的边界

file2x 经 snake_case 转换后是什么?主流约定(lodash、change-case、PEP 8、大小写转换)把每一次字母↔数字过渡都当作 token 边界,所以 file2x 被切成 file / 2 / x,snake_case 化后是 file_2_xparseUTF8 被切成 parse / utf / 8,结果是 parse_utf_8

某些老库以及 Stack Overflow 上的手写 re.sub 片段会跳过这条规则,把 file2x 原样保留,把 parseutf8 拼在一起。这种不匹配只在跨库迁移代码时浮出水面,症状是「一半标识符被改名、另一半没改」。挑一个分词器,确认它遵守数字边界规则,然后一直用它。

2. 连续的大写字母

缩写边界的正则是 /([A-Z]+)([A-Z][a-z])/,在「一段大写」和「一个大写起首新词」之间切开。XMLHttpRequest 匹配成 XML + HttpRequest,再拆 Http + Request,最终得到 token XML / Http / Request

反向回去时问题就来了:XML / Http / Request 再 PascalCase 化得到 XmlHttpRequest,不是 XMLHttpRequest,缩写被 title-case 化了。这是标准行为,另一种做法需要分词器没有的带外元数据来记住哪些 token 原本是缩写。如果代码库使用 XMLHttpRequest 风格,又用一个普通词转换器在项目范围内做改名,每一个缩写都会被悄无声息地重写。先在分支上跑测试,或者用一个允许显式标记缩写的分词器。

3. Unicode 与 locale 感知的大小写映射

JavaScript 里 'I'.toLowerCase() 通常返回 'i'。在土耳其 locale 激活时同样的调用返回 'ı'(无点 i,U+0131),因为土耳其语有两个 i 字母,大写 I 的小写形式正是无点的那一个。这个 bug 在国际化上线时反复出现:登录表单把用户名转大写后比对,土耳其用户 İrem 永远登不进自己的账号。

还有两个雷区。德语的 ß.toUpperCase() 返回 'SS',一个字符变成两个,任何假定 case 转换保留字符串长度的代码都会出错。希腊语 Σ.toLowerCase() 是上下文相关的:词中是 σ,词末是 ς

修复:用带显式 locale 的 toLocaleLowerCase()toLocaleUpperCase();不知道用户 locale 时传 'en-US' 拿到 ASCII 兼容的行为。大小写转换使用 Intl 感知的方法,能正确处理上述三个输入。正则那一面,正则表达式完全指南讲了 \p{L} 这个 Unicode 字母类。

4. 智能引号污染

从 Microsoft Word、Google Docs 或 macOS 备忘录粘贴字符串到 case 转换器里,可能携带一批隐形字符:U+2018 / U+2019 / U+201C / U+201D(弯引号)、U+2014(长破折号)、U+00A0(不间断空格)、U+200B(零宽空格)。这些字符在多数字体里看起来与 ASCII 版本相同,编码却不同。包含 U+00A0 的 camelCase 标识符在某些语言能编译、另一些不能;用 grep 搜变量名时也会漏掉。

防御:分词前先归一化输入。一行 input.normalize('NFKC').replace(/[“”‘’]/g, '"') 能处理掉大部分。或者参考文本对比在线工具指南的做法,把可疑字符串和它的 ASCII 形态做 diff,在 hex 视图里定位隐形字符。

5. URL 不该被 snake_case 化

https://example.com/api/users 粘进 snake_case 转换器会变成 https_example_com_api_users。技术上是合法的 snake_case 标识符,语义上没有意义。URL 已经处在 canonical case 上(path/case,路径段是小写 kebab-case),把整个 URL 当作单一标识符处理会丢掉结构信息。

修复办法是先解析 URL,提取路径段,需要时对每段单独转换。大小写转换刻意不自动解析 URL:猜测意图比字面处理更危险。粘 URL 就字面转换,需要分段处理就自行分段。

6. dot.case 与属性访问

字符串 user.profile.image 在不同上下文里是两种不同的东西。在 TOML 文件里作为 dot.case 标识符,它是一个由三段组成的名字。作为 JavaScript 表达式,它是 userprofile 属性的 image 属性。

把 dot.case 字符串从配置文件复制到 JavaScript 控制台,运行时会把它当属性链求值,要么报错,要么返回意外结果。反过来,处理 JS 属性路径的代码('a.b.c'.split('.'))有时也会处理来自配置的 dot.case 标识符,把它当成比预期更深的路径。两者必须保持命名空间分离。

约定:dot.case 字符串只在数据里出现(配置文件、MongoDB 路径、日志键);单一标识符的代码用 camelCase 或 snake_case;代码里需要层级结构时,用嵌套对象加宿主语言的点属性语法。

跨语言迁移配方

JS camelCase 转 Python snake_case

最快的流程是复制 JS 标识符,粘到转换器里,复制 snake_case 输出。批量做代码级转换:

import { snakeCase } from 'change-case';

snakeCase('parseHTML');         // 'parse_html'
snakeCase('XMLHttpRequest');    // 'xml_http_request'
snakeCase('parseUTF8');         // 'parse_utf_8'
snakeCase('iPhone');            // 'i_phone'

最后一个是坑。iPhone 是品牌名,camelCase 边界误导了分词器。品牌名以及少数历史标识符,转换后要手动修一遍。

SQL snake_case 转 JS/Java API 响应

绝大多数 ORM 会自动处理。Sequelize 有 underscored: true,TypeORM 有 SnakeNamingStrategy 类,Hibernate 有 ImplicitNamingStrategyComponentPathImpl。默认映射是 user_profile_iduserProfileId

会出问题的地方是带缩写的列。名为 http_status_code 的列能干净地往返为 httpStatusCode,但代码库偏好 HTTPStatusCode 时 ORM 会和它打架。要么把列改成 httpstatuscode_code(不好看),要么配置 ORM 保留缩写(少见),要么接受标准约定。

React PascalCase 组件转 CSS kebab-case 类名

// UserProfileCard.tsx
export function UserProfileCard({ user }) {
  return <div className="user-profile-card">{user.name}</div>;
}
/* UserProfileCard.module.css */
.user-profile-card { padding: 1rem; }
.user-profile-card__avatar { border-radius: 50%; }
.user-profile-card--featured { background: gold; }

BEM(Block Element Modifier)是和 React 最常配对的 CSS 类名约定:block 是 kebab-case 的组件名,element 是 block__element,modifier 是 block--modifier。文件层面:组件用 UserProfileCard.tsx,作用域样式用 UserProfileCard.module.css,两者都是 PascalCase,与组件同名。

环境变量到应用配置

# .env (CONSTANT_CASE)
DATABASE_URL=postgres://localhost/myapp
MAX_RETRIES=3
LOG_LEVEL=info
// Node.js
const dbUrl = process.env.DATABASE_URL;
const maxRetries = parseInt(process.env.MAX_RETRIES, 10);
# Python
import os
db_url = os.environ['DATABASE_URL']
max_retries = int(os.environ['MAX_RETRIES'])

环境变量名保持 CONSTANT_CASE,应用侧的标识符跟随该语言的变量约定。YAML/TOML 配置键按惯例是 snake_case(database_urlmax_retries),即便运行时映射到同一批 CONSTANT_CASE 环境变量。Spring、dotenv、Pydantic 这类框架会处理 case 映射。

库与工具对比

工具语言支持的 case分词器行为
lodash(_.camelCase 等)JavaScript4 种主流 + startCase缩写当作普通词
change-case npm 包JavaScript/TS全部 8 种编程 case缩写当作普通词
inflection(Python)PythoncamelCase / snake_case缩写当作普通词
convert_case crateRust12+ 种 case可配置缩写处理
Go strings + 正则Go手写实现项目自定义
VS Code(内置)编辑器仅 UPPER / lower / Title只按空白分
VS Code「change-case」扩展编辑器全部 8 种编程 case缩写当作普通词
大小写转换浏览器15 种 case(7 文本 + 8 代码)缩写当作普通词

日常代码开发装 change-case(JS)或 convert_case(Rust)。Python 用 inflection 是经典选择,一段简短的手写正则也能覆盖 90% 的场景。code review 或重构时的零散转换,大小写转换在一次粘贴里展示全部 15 种输出,方便对比。需要统计 token 数或验证标识符长度时用字数统计;验证分词正则可以用正则表达式测试配合上文链接里的速查表模式。

FAQ

camelCase 和 PascalCase 有什么区别?

camelCase 以小写字母开头(userProfile),PascalCase 以大写字母开头(UserProfile)。两者后续单词首字母都大写,且无分隔符。camelCase 是大多数 C 系语言里变量与函数的约定,PascalCase 用于类、类型和 React 组件。

为什么 Python 用 snake_case,JavaScript 却用 camelCase?

Python(1991)从 C 和 ABC 语言继承了 snake_case,PEP 8 把它定为社区标准。JavaScript(1995)沿用了 Java 的 camelCase 风格,Java 又承袭自 Smalltalk。两者都是历史路径依赖。哪种约定都谈不上更优(可读性研究的结果大致打平),生态内部的一致性比选哪种更重要。

camelCase 里的缩写该写 parseUrl 还是 parseURL?

parseUrl(把缩写当作普通词)是现代默认,Google、Apple、lodash、change-case npm 包都这么用。parseURL(保留缩写大写)是 Microsoft .NET 风格,在 C# 代码里占主导。新建 JavaScript、TypeScript 或 Swift 项目选 parseUrl,因为它能在 snake_case 和 kebab-case 之间干净地往返。无论选哪种,都要写进 lint。

URL 用 kebab-case 比 snake_case 好吗?

是的。Google Search Central 的官方建议是 URL 里用连字符,不用下划线。搜索索引在连字符处切词,不在下划线处切:/user-profile 被索引为 user + profile/user_profile 被索引为单一词项 user_profile。每页的排名影响小但真实存在,小写 kebab-case URL 还能避免 Linux 服务器上的大小写敏感性 bug。

数据库列名应该用什么 case?

snake_case。主流 ORM(SQLAlchemy、Hibernate、Sequelize、TypeORM、Active Record)默认用它,主流 SQL 方言对它的处理一致。PostgreSQL 把未加引号的标识符折叠成小写,MySQL 在 Linux 区分大小写、在 macOS/Windows 不区分,SQLite 把名字当作不透明字符串。小写 snake_case 是在所有环境下行为一致的写法。

一个项目里可以混用多种命名约定吗?

可以,而且通常必须如此。一个典型 Web 应用会在 JS 变量用 camelCase、数据库用 snake_case、CSS 类与 URL 用 kebab-case、环境变量用 CONSTANT_CASE。规则是一层一种约定,单层之内不混用。把每一层的选择写进 lint 或风格指南,PR review 不会再为它浪费一个字。

如何用程序在 case 之间转换?

JavaScript 和 TypeScript 装 change-case,或用 lodash 的 _.camelCase / _.snakeCase / _.kebabCase。Python 用 inflection 包,或一段短正则(PascalCase 转 snake_case 是 re.sub(r'(?<!^)(?=[A-Z])', '_', s).lower())。Rust 用 convert_case crate。一次性交互转换用大小写转换,在浏览器单页里展示任意输入的 15 种 case 输出。

CONSTANT_CASE 只用于环境变量吗?

不是,但环境变量是最常见的用法。CONSTANT_CASE 用于任何运行时不变量:MAX_RETRIESAPI_BASE_URLDEFAULT_PAGE_SIZE、enum 值、宏定义、顶层配置常量。判断标准是「运行时改这个值算不算 bug」:算就用 CONSTANT_CASE,否则用语言里普通的变量约定。const result = await fetch(url) 保持原样即可。

dot.case 和 path/case 有什么区别?

dot.case 用 . 作分隔符(user.profile.image),表达数据内部的层级键:Java 包、MongoDB 字段路径、TOML 配置键、Lodash get/set 路径。path/case 用 /user/profile/image),表达真实位置:URL 路径、文件系统路径、Git 引用。点和斜杠的差别在于数据标签与实际位置的语义。

30 秒决策清单

三条规则就能覆盖 95% 的问题:

  1. 写代码时跟着所在语言的标准库。Python:变量与函数 snake_case,类 PascalCase。JavaScript 和 TypeScript:变量与函数 camelCase,类与组件 PascalCase。Go:包级私有用小写起首,导出用大写起首。Rust:变量与函数 snake_case,类型 PascalCase,常量 SCREAMING_SNAKE。

  2. 跨语言的横切层,case 是固定的。URL 永远 kebab-case。CSS 类名永远 kebab-case。数据库列名永远 snake_case。环境变量永远 CONSTANT_CASE。HTTP/1.1 头部永远 Header-Case(HTTP/2 在传输层会归一化为小写)。

  3. 把选择写进 lint,一次性结束争论。ESLint、Pylint、Clippy、golangci-lint、Rubocop 都有对应规则。选好约定、配好 lint,下一次 PR review 就不会再为 userID 还是 userId 多花一个字。

需要在 case 之间转换(重构、CMS 迁移、SQL 到 API 的映射)时,大小写转换能在一次粘贴里给出全部 15 种输出,复制需要的那个即可,不必手工分词。其他文本工具见字数统计正则表达式测试文本对比在线工具。深入阅读:正则表达式完全指南讲分词器需要的模式,文本对比在线工具指南讲迁移过程中的前后对比,字符与字数限制完全指南讲 SEO slug 的 URL 长度预算。