如何在Lisp(SBCL)中用subseq提取冒号与分号间的子串?
在SBCL中提取冒号和分号包裹子串的问题解决
问题原因
你写的(subseq "8.I:123;" : ;)触发语法错误,核心原因有两点:
- Lisp中
:开头的是关键字符号,单独写: ;会让解析器认为是不完整的关键字定义,直接触发非法字符报错 subseq函数要求的起始、结束参数必须是整数索引,不能直接传入标点符号或关键字
解决步骤
1. 手动定位索引提取
先通过position函数找到冒号和分号在字符串中的位置,再用subseq提取目标子串:
;; 查找冒号的索引(字符串索引从0开始) (position #\: "8.I:123;") ; 返回4 ;; 查找分号的索引 (position #\; "8.I:123;") ; 返回8 ;; 提取冒号后、分号前的子串(起始索引为冒号位置+1,结束索引为分号位置) (subseq "8.I:123;" 5 8) ; 返回"123"
2. 封装通用函数
如果需要批量处理类似格式的字符串,可以封装一个自动处理的函数:
(defun extract-between-colon-semicolon (input-str) (let ((colon-pos (position #\: input-str)) (semicolon-pos (position #\; input-str))) ;; 检查两个符号都存在,且分号在冒号后方 (when (and colon-pos semicolon-pos (> semicolon-pos colon-pos)) (subseq input-str (1+ colon-pos) semicolon-pos))))
调用示例:
(extract-between-colon-semicolon "8.I:123;") ; 返回"123" (extract-between-colon-semicolon "demo:hello-world;test") ; 返回"hello-world"
额外说明
如果字符串中存在多个冒号或分号,可以通过position的:from-end参数调整查找方向,比如定位最后一个冒号:
(position #\: "a:b:c:d;" :from-end t) ; 返回6
内容的提问来源于stack exchange,提问作者Oliver Cox
相关产品推荐
相关产品推荐

