我有一个查询请求uri,格式为“/node/143”(只是格式的示例)。
我想从字符串中去除第一个正斜杠,我查找了函数remove并进行了尝试。我似乎无法正常工作(我在Linux上使用SBCL)。
我已经使用此代码设置了request-uri。
(setq request-uri "/node/143")
当我检查变量时,我将其返回。
request-uri
"/node/143"
现在,我尝试删除第一个斜杠(此时,就可以看到该函数的正确使用方式了。)
(remove "/" request-uri)
"/node/143"
(remove '/ request-uri)
"/node/143"
我什至尝试提供 list
(remove '("/") request-uri)
"/node/143"
(remove '('/) request-uri)
"/node/143"
即使字符串是vectors of characters,我也认为可能以某种方式将整个字符串放在一个单元格中,并且我试图删除整个字符串,但还是没有运气。
(remove "/node/143" request-uri)
"/node/143"
(remove '/node143 request-uri)
"/node/143"
所以我现在很茫然,这个看似简单的功能真的让我望而却步,我以为我遵循了文档的内容,但是没有任何效果。
任何人都可以对这里发生的事情有所了解吗?
谢谢。
编辑:我找到了问题的答案,这引发了另一个问题。
从我使用的字符串中删除一个元素
(remove #\/ request-uri)
整个字符串呢
`(remove #\node request-uri`)
仅适用于第一个字符并引发错误,随后的所有字符均不起作用。
(remove "node" request-uri)
(remove 'node request-uri)
(remove ?\node request-uri)
(remove #\node request-uri)
(remove '("node") request-uri)
我不确定在这里应该如何解决。
最佳答案
学习阅读Common Lisp HyperSpec。
字符串是Sequences,Arrays(字符的一维向量),还有Strings。这意味着大多数这些功能都适用。
让我们看看REMOVE。 CLHS给出以下签名:
remove item sequence &key from-end test test-not start end count key
=> result-sequence
字符串是字符序列。因此,调用remove将是:
(remove #\/ "/foo/")
或(例如)
(remove #\/ "/foo/" :start 2)
请记住:
#\a
是一个字符。 #\node
没有字符。非法的。字符串是"/foo/"
。要从字符串中删除的项目必须是字符。没有其他的。为什么?由于TEST默认为EQL,因此EQL会将字符串中的字符与您的item参数进行比较。默认情况下,键也是IDENTITY,并且不会更改项目。
如果您的参数是字符串怎么办?好吧,那么您必须做更多的事情:
(remove "/" "/abc/" :key #'string :test #'equal)
这将查看序列中的每个字符并将其变成字符串。然后,将使用函数EQUAL将字符串与您的项目
"/"
比较。这也可以。代价是它需要从"/abc/"
的每个字符生成一个字符串,每个字符串都是一个新对象。另一种方法是:
(remove "/" "/abc/" :test (lambda (a b) (eql (aref a 0) b)))
上面的代码在每个测试中检索
"/"
的第一个字符,并将其与字符串"/abc/"
中的字符进行比较。同样,代价是它需要获得5次字符(在此示例中)。因此,如果原始对象以字符串形式出现,则最好的编写方式是:
(remove (aref "/" 0) "/abc/")
在上面,我们从字符串
"/"
中一次获得了字符,然后REMOVE将该字符与默认EQL测试与字符串中的每个字符进行比较-它向#\/
返回一个不是EQL的字符的新字符串。您期望?\foo是什么?在Common Lisp中,这是符号
|?fOO|
。由于字符串(此处为
(remove "foo" "afoob")
)不是字符串的元素,因此"foo"
也不起作用。请记住,字符是字符串的元素。还请记住,带有诸如"/"
之类的一项的字符串仍然是字符串,而不是字符。因此,"/"
和#\/
是不同的类型。第一个是字符串,第二个是字符。SUBSEQ从序列中提取序列。这意味着它还会从另一个字符串中提取一个字符串:
(subseq "0123456" 1 5)
where 1 is the start and 5 is the end index.
CONCATENATE追加序列。这意味着它还会附加字符串。
(concatenate 'string "abc" "123")
returns a new string with the strings "abc" and "123" appended.
要删除字符串的一部分,另请参见功能STRING-TRIM,STRING-LEFT-TRIM和STRING-RIGHT-TRIM。
因此,就像从字符串中删除子字符串的另一种答案一样,您需要编写一些代码以提取一些字符串,然后将它们串联起来。
SEARCH在字符串中搜索字符串。