我一直在尝试使用langutils库(我使用Quicklisp下载)对字符串进行标记,我正在使用SBCL,但我遇到了一些问题。我一直在尝试使用以下代码:
(cl-utilities:split-sequence #\Space (multiple-value-call #'(lambda (a b c d) c) (tokenize-stream (open "hello.txt"))))
输出
("Hello" "," "" "what" "is" "your" "name." "My" "name" "is" "John" "Doe.")
我的问题是:为什么语言标记空间,为什么不标记句点?
顺便说一句,如果说有些错误,那么我可以使用Common Lisp中的其他替代库吗?我曾尝试使用(tokenize-file),但它运行不正常 - 使用(tokenize-file“hello.txt”)返回
The function LANGUTILS-TOKENIZE:TOKENIZE-FILE is undefined.
并使用(标签“string”)返回
The value NIL is not of type HASH-TABLE.
答案 0 :(得分:1)
好的,让我们看一下,没有特别的顺序:
是的,langutils
似乎有些错误。看看它的来源,很多东西仍被标记为“(尚未实施)”。你想用它做什么?具体来说,您期望(tag "string")
和tokenize-file
做什么(文档字符串不是特别清楚)?
如果您要尝试解析Lisp表达式,可以使用内置的read
。如果您打算尝试使用自己的语法规则解析任意文件(并使用SBCL),请查看esrap
。它是Common Lisp中的PEG解析器实现。 github有一些例子。
如果要忽略split-sequence
中的空序列,可以向其传递额外的:remove-empty-subseqs
关键字参数。我不完全确定为什么这不是默认值,因为我从未在没有此选项的情况下调用该函数,但它可能在任何主要用例中都有意义。
您的通话应该是
(cl-utilities:split-sequence
#\Space (multiple-value-call #'(lambda (a b c d) c)
(tokenize-stream (open "hello.txt")))
:remove-empty-subseqs t)
tokenize-stream
似乎返回文件的文本内容以及有关它的一些元数据。如果这就是你想要的,那么在不诉诸multiple-value-call
的情况下编写自己的代码非常容易。请参阅Files and Directories section of the CL Cookbook
我认为通过执行(tokenize-stream (open "hello.txt"))
,你会留下悬挂的文件句柄(因为你之后不会关闭它)。这里典型的做法是致电with-open-file
(with-open-file (s "hello.txt")
(tokenize-stream s))