我需要帮助编程。我在Common Lisp中编码,我正在尝试从字符串列表中删除标签。我读了一个XML格式的文件,我的目标是删除<
和>
之间出现的任何文字,如果标记以?xml
开头,那么整行需要被删除。我知道命令行上有remove
/delete
/函数可用,但我试图在我的实际Lisp代码中进行删除,我无法弄清楚如何去做。每次我尝试都会收到错误。
现在这里是我在文件中阅读的代码(可行):
;;;Program: Lisp Assignment 1
;;;Author: Mouse
(defun file-lines (file)
;;;returns a list of strings and the number of
;;;lines read.
(with-open-file (i file)
(loop for line = (read-line i nil nil)
and line-count from 0
while line
collect line into lines
finally (return (values lines line-count)))))
我的想法是,在显示while line
的行之后,我将不得不输入代码来检查标记,但我不知道该使用什么。每次我调用remove
或delete
方法时,都会收到错误消息。我不知道我是不是正确地称呼他们。有人可以帮忙吗?
答案 0 :(得分:1)
我认为你的问题不是很清楚。为什么要询问从字符串列表中删除标记,而示例代码从文件中读取行?假设你真的在问一个字符串列表,那么标签可能会分布在多个字符串上吗?此外,您询问的是remove
和delete
,但未提及您的确尝试过以及失败的原因。如果你想直接改变文件的内容,那么你不能只从流中删除东西并期望它能够工作。
这是一种通过逐字符读取流来删除标记的简单方法:
(defun remove-tags (string)
(flet ((read-tag (instream)
(loop for char = (read-char instream nil nil)
while (not (string= char #\>)))))
(with-output-to-string (outstream)
(with-input-from-string (instream string)
(loop for char = (read-char instream nil nil)
while char
if (char= char #\<) do (read-tag instream)
else do (write-char char outstream))))))
CL-USER> (remove-tags "<p><a href=\"foo\">bar</a> frob <emph>baz</emph> quux</p>")
"bar frob baz quux"
如果您想要读取和写入文件,只需将with-output-to-string
和with-input-from-string
替换为相应的with-open-file
表单。
但这只是一个让你入门的例子。即使这只是一个学术练习,你需要使它更加健壮。例如,它失败了:
CL-USER> (remove-tags "<p><a href=\"fo>o\">bar</a>")
"o\">bar"
(如果我没记错的话,XML字符串中允许使用未转义的结束尖括号。)
此外,这既没有经过测试也没有针对速度进行优化 - 处理字符可能太慢,并且它不处理?xml
标记的删除。所有这些都留给读者练习。
对于实际目的,您可能真的只使用其中一个XML库,或者使用regexen并祈祷。解析和处理XML是一个问题,已经在许多库中以实际使用的几乎所有语言解决了,并且有很多细节可能出错(如果你真的只是想删除一些标签,那可能不是,但是 principiis obsta ),无论如何它都是一项相当无聊的练习。