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

string list input split lisp

12904 观看

5回复

81 作者的声誉

我正在尝试将用户输入并将其存储在列表中,而不是仅包含单个字符串的列表,我希望扫描的每个单词都是自己的字符串。例:

> (input)
This is my input. Hopefully this works

会回来:

("this" "is" "my" "input" "hopefully" "this" "works")

请注意我在最终列表中不需要任何空格或标点符号。

任何投入将不胜感激。

作者: Sean Evans 的来源 发布者: 2013 年 3 月 13 日

回应 5


19

40127 作者的声誉

split-sequence 是现成的解决方案。

你也可以自己动手:

(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 " ,.;/"))

PS。看着你期望的回报值,你似乎想要string-downcase之前打电话my-split

PPS。你可以很容易地修改my-split接受:start:end:delimiterp&C。

购买力平价。对于前两个版本的错误抱歉my-split。请考虑一个指标,即应该使用此功能的自己版本,而是使用现成的解决方案。

作者: sds 发布者: 2013 年 3 月 13 日

1

352 作者的声誉

; in AutoLisp usage (splitStr "get off of my cloud" " ") returns (get off of my cloud)

(defun splitStr (src delim / word letter)

  (setq wordlist (list))
  (setq cnt 1)
  (while (<= cnt (strlen src))

    (setq word "")

    (setq letter (substr src cnt 1))
    (while (and (/= letter delim) (<= cnt (strlen src)) ) ; endless loop if hits NUL
      (setq word (strcat word letter))
      (setq cnt (+ cnt 1))      
      (setq letter (substr src cnt 1))
    ) ; while

    (setq cnt (+ cnt 1))
    (setq wordlist (append wordlist (list word)))

  )

  (princ wordlist)

  (princ)

) ;defun
作者: Stephen 发布者: 2014 年 7 月 25 日

2

9112 作者的声誉

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

http://weitz.de/cl-ppcre/#split

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

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

你有cl-slug删除非ascii字符和标点符号:

 (asciify "Eu André!") ; => "Eu Andre!"
作者: Ehvince 发布者: 2017 年 1 月 3 日

0

1 作者的声誉

(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)))))
)
作者: Henadzi Siarchenia 发布者: 2017 年 6 月 8 日

1

660 作者的声誉

对于Common-Lisp中的那个任务,我觉得很有用,一般来说,(uiop:split-string str :separator " ")uiop有很多实用工具,看看文档https://common-lisp.net/project/asdf/uiop.html#index-split_002dstring

作者: hsrv 发布者: 2019 年 1 月 14 日
32x32