在Lisp中将字符串拆分为列表后如何修剪

时间:2016-07-08 05:49:40

标签: lisp common-lisp

以下代码来自https://www.rosettacode.org/wiki/Tokenize_a_string#Common_Lisp,用逗号分隔字符串并发送一个列表。

(defun comma-split (string)
  (loop for start = 0 then (1+ finish)
        for finish = (position #\, string :start start)
        collecting (subseq string start finish)
        until (null finish)
  )
)

但是,如果子串在原始字符串中,则它们周围会有空格。

> (comma-split " a, b ,c , d ,   e")
(" a" " b " "c " " d " "   e")

如何在此处添加字符串修剪功能以删除这些空格。我看不到函数中返回的字符串变量。

我尝试使用局部变量,但它不起作用:

(defun comma-split2 (string)
(let* ( (onestr "")
     ) 
  (loop for start = 0 then (1+ finish)
        for finish = (position #\, string :start start)
        (onestr (subseq string start finish))
        (onestr (string-trim onestr))
        collecting onestr
        until (null finish)
  )
))

加载文件时出错:

*** - LOOP: illegal syntax near (ONESTR (SUBSEQ STRING START FINISH)) in
       (LOOP FOR START = 0 THEN (1+ FINISH) FOR FINISH = (POSITION #\, STRING :START START) (ONESTR (SUBSEQ STRING START FINISH))
        (ONESTR (STRING-TRIM ONESTR)) COLLECTING ONESTR UNTIL (NULL FINISH))
The following restarts are available:

即使在第二个函数中修剪outlist也无法正常工作:

(defun comma-split2 (string)
(let ( (outlist (list))
    (setf outlist (comma-split string))
    (dolist (str outlist)
        (push (string-trim str) outlist)
    )
    (nreverse outlist)
)))

> (comma-split2 " a, b ,c , d ,   e")

*** - LET: illegal variable specification (SETF OUTLIST (COMMA-SPLIT STRING))
The following restarts are available:

4 个答案:

答案 0 :(得分:3)

COLLECTING - 语句是创建列表的内容。因此,您需要将STRING-TRIM的呼叫围绕正在收集的内容。

(defun comma-split (string)
  (loop for start = 0 then (1+ finish)
        for finish = (position #\, string :start start)
        collecting (string-trim " " (subseq string start finish))
        until (null finish)))

你不应该把右括号放在他们自己的行上。

答案 1 :(得分:1)

您的代码无效LOOP语法。 您可以使用简单的语法,类似于PROGN但循环,或者您使用LOOP关键字,在这种情况下,您需要使用DO前缀语句:

(loop 
  for i in list
  do
    (print i)
    (sleep 1))

您可能只需要这样做:

(loop for start = 0 then (1+ finish)
      for finish = (position #\, string :start start)
      collect (string-trim " " 
                           (subseq string 
                                   start 
                                   finish))
      until (null finish))

或者,使用正则表达式(参见http://weitz.de/cl-ppcre/):

(ppcre:split " *, *" string)

答案 2 :(得分:1)

如果没有适当的缩进Lisp代码,你就不会走得太远。

唐' T:

(defun foo (a)
(let ((b )
 b
))
 )

(defun foo (a)
   (let (b)
     b))

另外:尝试编写Lisp代码而不理解Lisp语法也不是一个好主意。

尝试通过Google搜索随机代码来使用复杂语言,尝试随机修改代码然后将错误消息发布到Stackoverflow并不是一种非常有前景的方法。

阅读一本或多本基本的Lisp书籍:

使用Lisp参考:Common Lisp Hyperspec

  

LOOP:

附近的非法语法

首先阅读LOOP。

  

LET:非法变量规范

由于缺少缩进和违反Lisp语法而导致。检查LET的语法。

  

如何添加字符串修剪功能以删除这些空格

如何添加功能?

鉴于此表达式:

(sin 3.0)

如何添加计算平方根的函数?

解决方案:

(sqrt (sin 3.0))

您可以在第一个结果上调用该函数。

这很简单。为什么还需要其他变量?

答案 3 :(得分:-1)

您可以使用方法string-trim。 例如

(string-trim '(#\Space #\Tab #\Newline) " Test   Test") =>  "Test Test" .

有关详情,请访问here

我希望这会对你有所帮助! :)