1

我需要帮助编程一些东西。我正在使用 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,我必须输入代码来检查标签,但我不知道该使用什么。每次我调用removeordelete方法时,都会出现错误。我不知道我是否没有正确地称呼他们或其他什么。有人可以帮忙吗?

4

1 回答 1

1

我认为你的问题不是很清楚。为什么你问从字符串列表中删除标签,而你的示例代码从文件中读取行?假设您确实在询问字符串列表,标签是否可以分布在多个这些字符串上?此外,您询问removedelete没有提及您真正尝试过什么以及它是如何失败的。如果您想直接更改文件的内容,那么您不能只是从流中删除内容并期望它起作用。

这是一种通过逐个字符读取流来删除标签的简单方法:

(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-stringwith-open-file

但这只是一个让您入门的示例。即使这只是一个学术练习,你也需要让它更加健壮。例如,它失败了:

CL-USER> (remove-tags "<p><a href=\"fo>o\">bar</a>")
"o\">bar"

(如果我没记错的话,XML 字符串中允许使用未转义的右尖括号。)

此外,这既没有经过测试也没有以任何方式优化速度 - 处理字符可能太慢,并且它不处理?xml标签的删除。所有这些都留给读者作为练习。

出于实际目的,您可能真的应该只使用其中一个 XML 库,或者使用 regexen 并祈祷。解析和处理 XML 是一个问题,在实际使用中几乎所有语言的许多库中都已解决,并且有很多细节会出错(如果你真的只是想删除一些标签,也许不是这样,但原则),无论如何,这都是一个相当无聊的练习。

于 2013-03-07T02:32:56.587 回答