Function CommonLisp:删除函数,它是如何使用的?

Function CommonLisp:删除函数,它是如何使用的?,function,common-lisp,sbcl,Function,Common Lisp,Sbcl,我有一个“/node/143”形式的查询请求uri(只是格式的一个示例) 我想从字符串中去掉第一个正斜杠,我查阅了函数并进行了尝试。我似乎无法让它工作(我在Linux上使用SBCL) 我已经使用此代码设置了请求uri (setq request-uri "/node/143") 当我检查变量时,我返回了这个 request-uri "/node/143" 我现在尝试删除第一个斜杠(在这一点上,看看函数是如何正确使用的) 我甚至试着提供一份清单 (remove '("/") request-u

我有一个“/node/143”形式的查询请求uri(只是格式的一个示例)

我想从字符串中去掉第一个正斜杠,我查阅了函数并进行了尝试。我似乎无法让它工作(我在Linux上使用SBCL)

我已经使用此代码设置了请求uri

(setq request-uri "/node/143")
当我检查变量时,我返回了这个

request-uri
"/node/143"
我现在尝试删除第一个斜杠(在这一点上,看看函数是如何正确使用的)

我甚至试着提供一份清单

(remove '("/") request-uri)
"/node/143"

(remove '('/) request-uri)
"/node/143"
即使字符串是,我想也许整个字符串可能被放在一个单元格中,我试图移除整个字符串,但仍然没有运气

(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)
我不确定这里应该如何处理它。

这失败了,因为“/”是字符串,而不是字符

(remove "/" request-uri)
"/node/143"
(remove #\/ request-uri)
"node143"
如果需要字符,则需要使用#/即正斜杠字符

(remove "/" request-uri)
"/node/143"
(remove #\/ request-uri)
"node143"
但正如您所看到的,它将删除所有正向斜杠。根据您链接的文档页面,remove采用名为:count的关键字参数,该参数表示要删除的项目数。所以你可以这样做

(remove #\/ request-uri :count 1)
"node/143"
希望这有帮助

::编辑::


不是?/,是#/。谢谢道格拉斯

要删除整个子字符串,您必须创建一个新函数,例如:

(defun remove-string (rem-string full-string &key from-end (test #'eql) test-not (start1 0) end1 (start2 0) end2 key) "returns full-string with rem-string removed" (let ((subst-point (search rem-string full-string :from-end from-end :test test :test-not test-not :start1 start1 :end1 end1 :start2 start2 :end2 end2 :key key))) (if subst-point (concatenate 'string (subseq full-string 0 subst-point) (subseq full-string (+ subst-point (length rem-string)))) full-string))) (从末端移除字符串(rem字符串完整字符串和键)(测试#'eql) 测试不在(start1 0)end1(start2 0)end2键) “返回删除rem字符串的完整字符串” (让((子点)搜索rem字符串完整字符串 :从一端到另一端 :测试测试:测试不测试不 :start1 start1:end1 end1 :start2 start2:end2 end2:key键) (如果是子点 (连接“字符串” (海底满串0海底点) (海底全串(+海底点(长度rem串))) 完整字符串() 这只是一个起点。我复制了搜索的所有选项,但我认为有些选项在这种情况下没有意义。至少这是可行的:

(remove-string "node" "this is a node or not") (删除字符串“node”“这是否为节点”) 对于更详细的案例,您可能应该看看cl ppcre,一个正则表达式库。

说明:

(remove "node" request-uri)
(remove 'node request-uri)
(remove ?\node request-uri)
(remove #\node request-uri)
(remove '("node") request-uri)
它们分别是:一个字符串、一个(带引号的)符号、一个(已计算的)符号、一个格式错误的字符文本和一个包含一个字符串的列表。从一个对象序列中删除一个对象,而字符串不是这些内容的序列

如果您只想删除字符串的一部分,SUBSEQ可能会执行以下操作:

(let ((uri "/node/143"))
  (when (string= (subseq uri 0 6) "/node/")
    (format t "user wants node ~D" (parse-integer (subseq uri 6)))))
对于更复杂的事情,您可能需要像cl-ppcre和/或split-sequence这样的库。(如果您正在使用Hunchentoot,您已经加载了前者。)

学习阅读

字符串是,(字符的一维向量)以及。这意味着这些功能中的大多数都是适用的

我们来看看。CLHS签字如下:

remove item sequence &key from-end test test-not start end count key
    => result-sequence
字符串是字符序列。因此,要求删除的电话是:

(remove #\/ "/foo/")
或(例如)

记住:
\a
是一个字符<代码>#\node不是字符。非法的。字符串是
“/foo/”

要从字符串中删除的项必须是字符。没有别的了。为什么?因为测试默认为EQL,EQL将字符串中的字符与项参数进行比较。默认情况下,密钥也是标识,不会更改项目

如果你的参数是字符串呢?那么,你必须做更多:

 (remove "/" "/abc/" :key #'string :test #'equal)
这将查看序列中的每个字符,并将其转换为字符串。然后,将使用函数EQUAL将该字符串与项目进行比较。这也行得通。代价是它需要从
“/abc/”
的每个字符生成一个字符串,每个字符串都是一个新对象

另一种方法是:

 (remove "/" "/abc/" :test (lambda (a b) (eql (aref a 0) b)))
上面检索每个测试中
“/”
的第一个字符,并将其与字符串
“/abc/”
中的字符进行比较。同样,代价是需要获得五次字符(在本例中)

因此,如果原始对象以字符串形式出现,那么最好的编写方法是:

(remove (aref "/" 0) "/abc/")
在上面,我们从字符串
“/”
中获取一次字符,然后REMOVE将该字符与默认EQL测试进行比较,并与字符串中的每个字符进行比较-它将不属于EQL的新字符串返回到
\/

你期望什么?\foo是什么?在公共Lisp中,这是符号
|?fOO |

另外,
(删除“foo”“afoob”)
不起作用,因为字符串(
“foo”
此处)不是字符串的元素。请记住,字符是字符串的元素。还请记住,带有一个项目(如
“/”
)的字符串仍然是字符串,而不是字符。因此,
“/”
\/
属于不同的类型。第一个是字符串,第二个是字符

(remove "/" request-uri)
"/node/143"
(remove #\/ request-uri)
"node143"
SUBSEQ从序列中提取序列。这意味着它还会从另一个字符串中提取一个字符串:

(subseq "0123456" 1 5)
     where 1 is the start and 5 is the end index.
连接附加序列。这意味着它还附加字符串

(concatenate 'string "abc" "123")
  returns a new string with the strings "abc" and "123" appended.
要删除字符串的某些部分,请参见函数string-TRIM、string-LEFT-TRIM和string-RIGHT-TRIM

因此,正如在另一个从字符串中删除子字符串的答案中一样,您需要编写一些代码来提取一些字符串,然后将它们连接起来

搜索在字符串中搜索字符串。

复制了您的代码exactl