Skip to content

LISP - 字符串比较

标准数值运算符(如 < 和 >)在 Common Lisp 中不适用于字符串比较。相反,Lisp 提供了专用的函数集,用于区分大小写和不区分大小写的字符串比较。

这些函数比简单的相等性检查更强大,因为它们可以比较子字符串并对字符串序列进行操作。

区分大小写不区分大小写描述
string=string-equal如果字符串完全相同则返回 T,否则返回 NIL。
string/=string-not-equal如果字符串不同,则返回第一个不匹配字符的索引,否则返回 NIL。
string<string-lessp如果 string1 在字典序上小于 string2,则返回不匹配索引,否则返回 NIL。
string>string-greaterp如果 string1 在字典序上大于 string2,则返回不匹配索引,否则返回 NIL。
string<=string-not-greaterp如果 string1 不大于 string2,则返回不匹配索引,否则返回 NIL。
string>=string-not-lessp如果 string1 不小于 string2,则返回不匹配索引,否则返回 NIL。

关键概念:许多比较函数返回一个“广义布尔值”。NIL 始终为假。任何其他值,包括像不匹配索引 0 这样的数字,都被视为真。

区分大小写的函数根据字符代码逐字符进行比较。大写字母与小写字母具有不同的代码。

(format t "'test' = 'Test' -> ~a~%" (string= "test" "Test"))
;; "test" 在字典序上大于 "Test",因为 't' > 'T'。
;; 函数返回第一个字符不匹配的索引。
(format t "'test' > 'Test' -> ~a~%" (string> "test" "Test"))
;; "apple" 小于 "banana"。不匹配发生在索引 1 ('p' vs 'a')。
(format t "'apple' < 'banana' -> ~a~%" (string< "apple" "banana"))

执行代码后,将返回以下结果:

'test' = 'Test' -> NIL
'test' > 'Test' -> 0
'apple' < 'banana' -> 1

不区分大小写的函数通常更适用于用户输入或应在语义上比较的文本,忽略大小写。

(format t "'test' equal 'Test' -> ~a~%" (string-equal "test" "Test"))
;; 忽略大小写时,“test”不大于“Test”。
(format t "'test' greaterp 'Test' -> ~a~%" (string-greaterp "test" "Test"))
;; 忽略大小写时,“apple”仍小于“banana”。
(format t "'apple' lessp 'banana' -> ~a~%" (string-lessp "apple" "banana"))

结果现在忽略了大小写:

'test' equal 'Test' -> T
'test' greaterp 'Test' -> NIL
'apple' lessp 'banana' -> 1

使用起始/结束索引比较子字符串

Section titled “使用起始/结束索引比较子字符串”

所有字符串比较函数都接受每个字符串的可选 :start 和 :end 关键字参数,允许你比较字符串的特定部分。

;; 比较第一个字符串中的子字符串 "world" 和第二个字符串。
(let ((s1 "hello world")
(s2 "world"))
(format t "Comparing substring: ~a~%"
(string-equal s2 s1 :start2 6)))

比较成功,因为我们只查看了 s1 的相关部分:

Comparing substring: T