如何在Common Lisp中正确大写含非字母数字字符的单词?
问题:仅将字符串首字符大写,避免特殊字符触发后续自动大写
- 需求:单个单词以字符串存储,需要将首字符大写,其余字符保持原大小写(例如输入"i'm"要得到"I'm")
- 尝试过的标准方法:
(string-capitalize str)(format nil "~@(~A~)" str)
- 遇到的问题:两种方法遇到特殊字符(如撇号)会重置大写规则,导致后续字母被强制转为大写,比如输入"I'm"会得到"I'M"
- 疑问:不想手动编写完整函数,希望找到标准库中被忽略的特性来实现需求
解决方案
Common Lisp标准库确实没有直接提供仅首字符大写的内置函数,但可以基于现有工具快速组合实现,比从头写逻辑更简洁可靠:
方法1:拆分字符串拼接处理
直接提取首字符转为大写,再拼接原字符串从第二个字符开始的部分:
(defun capitalize-first-char (str) (if (zerop (length str)) str (concatenate 'string (string (char-upcase (char str 0))) (subseq str 1))))
测试:(capitalize-first-char "i'm") → "I'm",完全符合需求。
方法2:利用format精准控制
format的~@(~A~)会把非字母字符当作单词分隔符,所以我们可以单独处理首字符,剩余部分用普通格式输出:
(defun capitalize-first-char-format (str) (if (zerop (length str)) str (format nil "~@(~C~)~a" (char str 0) (subseq str 1))))
测试:(capitalize-first-char-format "i'm") → "I'm",效果一致。
补充说明
string-capitalize的设计目标是处理多单词的标题式大写(空格分隔的每个单词首字母大写),所以会把非字母字符识别为单词边界,这是它的设计特性而非bug。仅首字符大写的需求相对场景单一,因此标准库没有内置对应函数,但用上述两种方式基于现有工具组合,已经足够简洁高效。
内容的提问来源于stack exchange,提问作者Oliver Cox
相关产品推荐
相关产品推荐

