拆分字符串后如何 trim 在 Lisp 中列出

How to trim after splitting a string to list in 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")

如何添加 string-trim 函数来删除此处的这些空格。我看不到函数中返回的字符串变量。

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

(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:

即使 trim 在第二个函数中使用 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:

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

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

如需了解更多信息,请访问 here

希望对您有所帮助! :)

您的代码是无效的 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)

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)))

您不应该将右括号单独占一行。

如果没有正确缩进 Lisp 代码,您将不会走得太远。

不要:

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

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

此外:在不了解 Lisp 语法的情况下尝试编写 Lisp 代码也不是一个好主意。

尝试通过谷歌搜索随机代码来使用复杂的语言,尝试随机修改代码,然后将错误消息发布到 Whosebug 并不是一个很有前途的方法。

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

使用 Lisp 参考:Common Lisp Hyperspec

LOOP: illegal syntax near

首先了解 LOOP。

LET: illegal variable specification

由于缺少缩进和违反 Lisp 语法造成的。检查 LET.

的语法

How can I add string-trim function to remove these spaces here

你是怎么添加功能的?

给出这个表达式:

(sin 3.0)

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

解决方案:

(sqrt (sin 3.0))

您根据第一个结果调用该函数。

就这么简单。为什么需要额外的变量?