String Lisp-将输入拆分为单独的字符串

String Lisp-将输入拆分为单独的字符串,string,list,input,split,lisp,String,List,Input,Split,Lisp,我试图获取用户输入并将其存储在一个列表中,只是希望扫描的每个单词都是自己的字符串,而不是由单个字符串组成的列表。 例如: 将返回: ("this" "is" "my" "input" "hopefully" "this" "works") 请注意,我不希望在最终列表中有任何空格或标点符号 任何意见都将不胜感激。是现成的解决方案 您也可以自己滚动: (defun my-split (string &key (delimiterp #'delimiterp)) (loop :for b

我试图获取用户输入并将其存储在一个列表中,只是希望扫描的每个单词都是自己的字符串,而不是由单个字符串组成的列表。 例如:

将返回:

("this" "is" "my" "input" "hopefully" "this" "works")
请注意,我不希望在最终列表中有任何空格或标点符号

任何意见都将不胜感激。

是现成的解决方案

您也可以自己滚动:

(defun my-split (string &key (delimiterp #'delimiterp))
  (loop :for beg = (position-if-not delimiterp string)
    :then (position-if-not delimiterp string :start (1+ end))
    :for end = (and beg (position-if delimiterp string :start beg))
    :when beg :collect (subseq string beg end)
    :while end))
其中,
delimiterp
检查是否要拆分此字符,例如

(defun delimiterp (c) (or (char= c #\Space) (char= c #\,)))

(defun delimiterp (c) (position c " ,.;/"))
另外,看看您的预期返回值,您似乎想在
我的拆分之前调用

PPS。您可以轻松地修改我的拆分,以接受
:开始
:结束
:分隔符RP
&c

购买力平价。很抱歉,
my split
的前两个版本中出现错误。请考虑一个指标,说明一个人不应该翻滚自己的版本,而是使用现成的解决方案。

<代码>;在AutoLisp使用中(splitStr“get off my cloud”“)返回(get off my cloud) (defun splitStr(src delim/单词字母) (setq单词表(列表)) (setq cnt 1)
(虽然(有
cl-ppcre:split

* (split "\\s+" "foo   bar baz
frob")
("foo" "bar" "baz" "frob")

* (split "\\s*" "foo bar   baz")
("f" "o" "o" "b" "a" "r" "b" "a" "z")

* (split "(\\s+)" "foo bar   baz")
("foo" "bar" "baz")

* (split "(\\s+)" "foo bar   baz" :with-registers-p t)
("foo" " " "bar" "   " "baz")

* (split "(\\s)(\\s*)" "foo bar   baz" :with-registers-p t)
("foo" " " "" "bar" " " "  " "baz")

* (split "(,)|(;)" "foo,bar;baz" :with-registers-p t)
("foo" "," NIL "bar" NIL ";" "baz")

* (split "(,)|(;)" "foo,bar;baz" :with-registers-p t :omit-unmatched-p t)
("foo" "," "bar" ";" "baz")

* (split ":" "a:b:c:d:e:f:g::")
("a" "b" "c" "d" "e" "f" "g")

* (split ":" "a:b:c:d:e:f:g::" :limit 1)
("a:b:c:d:e:f:g::")

* (split ":" "a:b:c:d:e:f:g::" :limit 2)
("a" "b:c:d:e:f:g::")

* (split ":" "a:b:c:d:e:f:g::" :limit 3)
("a" "b" "c:d:e:f:g::")

* (split ":" "a:b:c:d:e:f:g::" :limit 1000)
("a" "b" "c" "d" "e" "f" "g" "" "")

对于常见情况,有(新的“现代且一致的”)字符串操作库:

(str:words "a sentence    with   spaces") ; cut with spaces, returns words
(str:replace-all "," "sentence") ; to easily replace characters, and not treat them as regexps (cl-ppcr treats them as regexps)
您必须删除非ascii字符和标点符号:

 (asciify "Eu André!") ; => "Eu Andre!"

以及
str:remove标点符号(使用
cl-change-case:no-case
)。

对于Common Lisp中的该任务,我发现有用
(uiop:split-string-str:separator“”)
和包
uiop
,一般来说,有很多实用程序,看一下文档。

Checkout它们有一系列常见的用例函数,其中一个是一个简单的空格分割,你可以修改它来删除标点等等。烹饪书在这里继续:我在分割序列上找到了很多材料,但显然我需要导入cl utilities包,我就是不知道该怎么做=/#imanewb@SeanEvans:小心!
import
是一个CL函数,您不想在这里使用它!您需要的是使用quicklisp:
(ql:quickload“split sequence”)等工具安装软件包
这帮了大忙。非常感谢。@sds:您的编辑破坏了您的代码(例如,使用
“a”
)进行测试。要澄清的是,第一个代码不能处理以分隔符结尾的字符串(例如
“abc”
),而第二个版本大多数情况下无法获取最后一个标记(例如
“ab cd”->(“ab”)
)。虽然这可能会回答问题,但最好提供代码的解释和任何可能有用的参考资料。有关回答问题的详细信息,请查看。
 (asciify "Eu André!") ; => "Eu Andre!"
(defun splitStr (src pat /)
    (setq wordlist (list))
    (setq len (strlen pat))
    (setq cnt 0)
    (setq letter cnt)
    (while (setq cnt (vl-string-search pat src letter))
        (setq word (substr src (1+ letter) (- cnt letter)))
        (setq letter (+ cnt len))
        (setq wordlist (append wordlist (list word)))
    )
    (setq wordlist (append wordlist (list (substr src (1+ letter)))))
)