Sean Evans
Sean Evans

Reputation: 261

Lisp - Displaying a String to List

I've been looking for a way to convert user input (read-line) to a list of atoms that I can manipulate more easily. For example:

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

and I want to get back.. (This is my input. Hopefully this works.)

Eventually it'd be ideal to remove any periods, commas, quotes, etc. But for now I just wanna store the users input in a list (NOT AS A STRING)

So. For now i'm using

(setf stuff (coerce (read-line) 'list))

and that returns to me as... (#\T #\h #\i #\s #\Space #\i #\s #\Space #\m #\y #\Space #\i #\n #\p #\u #\t #. #\Space #\H #\o #\p #\e #\f #\u #\l #\l #\y #\Space #\t #\h #\i #\s #\Space #\w #\o #\r #\k #\s #.)

So now i'm on the hunt for a function that can take that list and format it properly... Any help would be greatly appreciated!

Upvotes: 0

Views: 686

Answers (2)

Rainer Joswig
Rainer Joswig

Reputation: 139401

What you want to do is to split a sequence of characters (a String) into a list of smaller strings or symbols.

Use some of the split sequence functions available from a Lisp library (see for example cl-utilities).

In LispWorks, which comes with a SPLIT-SEQUENCE function) I would for example write:

CL-USER 8 > (mapcar #'intern
                    (split-sequence '(#\space #\.)
                                    "This is my input. Hopefully this works."
                                    :coalesce-separators t))
(|This| |is| |my| |input| |Hopefully| |this| |works|)

Remember, to get symbols with case preserving names, they are surrounded by vertical bars. The vertical bars are not part of the symbol name - just like the double quotes are not part of a string - they are delimiters.

You can also print it:

CL-USER 19 > (princ (mapcar #'intern
                            (split-sequence '(#\space #\.)
                                            "This is my input. Hopefully this works."
                                            :coalesce-separators t)))
(This is my input Hopefully this works)
(|This| |is| |my| |input| |Hopefully| |this| |works|)

Above prints the list. The first output is the data printed by PRINC and the second output is done by the REPL.

If you don't want symbols, but strings:

CL-USER 9 > (split-sequence '(#\space #\.)
                            "This is my input. Hopefully this works."
                            :coalesce-separators t)
("This" "is" "my" "input" "Hopefully" "this" "works")

Upvotes: 5

jwmc
jwmc

Reputation: 561

Rainer's answer is better in that it's a bit more lightweight (and general), but you could also use CL-PPCRE , if you already have it loaded (I know I always do).

You can use SPLIT directly on the string you get from READ-LINE, like so:

(cl-ppcre:split "[ .]+" (read-line))

(Now you have two problems)

Upvotes: 5

Related Questions