我有一个查询请求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

字符串是SequencesArrays(字符的一维向量),还有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在字符串中搜索字符串。

10-04 10:50
查看更多