大小写转换
将字母的大写 (uppercase) 和小写 (lowercase) 相互转换的处理。不同语言的转换规则各异,某些情况下转换还会导致字符数发生变化。
大小写转换 (case conversion) 是文本处理中最常见的操作之一。英语中"A"转为"a" (小写化) 或"hello"转为"HELLO" (大写化),26 个字母一一对应。然而放眼全球语言,大小写转换的复杂程度远超想象。虽然中文本身没有大小写的概念,但在处理中英混排文本、编程和国际化场景中,大小写转换仍然是不可回避的问题。
最著名的例外是德语的 ß (Eszett)。小写的"ß"大写化后变为"SS" (2 个字符),也就是说大写化会增加字符数。2017 年 Unicode 5.1 新增了大写的"ẞ",但德语正字法中仍以转换为"SS"为标准。土耳其语中"i"的大写是"İ" (带上点),"I"的小写是"ı" (无点),与英语的转换规则完全不同。
在编程中,不区分大小写的比较 (case-insensitive comparison) 经常被用到。电子邮件地址的本地部分区分大小写,但域名部分不区分;URL 的协议名 (http/HTTP) 和主机名不区分大小写,但路径部分区分。正确处理这些差异,需要明确在哪些部分执行不区分大小写的比较。
JavaScript 的 toLowerCase() 和 toUpperCase() 支持 Unicode,但涉及特定语言环境的转换时需要使用 toLocaleLowerCase()。在土耳其语环境下执行 'I'.toLocaleLowerCase('tr') 返回"ı",而英语环境下返回"i"。忽略语言环境的转换是国际化 (i18n) 中常见的 bug 来源。对于面向全球用户的中文应用,在处理用户输入的英文内容时同样需要注意这一点。
作为命名规范的大小写使用也很重要。camelCase (驼峰命名)、PascalCase (帕斯卡命名)、snake_case (蛇形命名)、kebab-case (短横线命名)、SCREAMING_SNAKE_CASE (常量命名) 等,编程中大小写模式承载着语义信息。这些转换不是简单的大小写化,而是需要识别单词边界后再进行转换。
从字符计数的角度看,大小写转换导致字符数变化的情况值得关注。除了前述的德语"ß"转为"SS"外,希腊语的"ς" (词尾 sigma) 转为大写"Σ"再转回小写时变为"σ" (词中 sigma),即小写形式会因位置不同而改变。在有字符数限制的输入框中执行大写化时,需要考虑转换后字符数可能超出限制的情况。