Potting Soil: Strings

by Larry Clapp

The subseq function lets you read from and write to specific portions of a string (or any sequence, by I'm focusing on strings here):

  (defparameter string (copy-seq "abcdefghijklmnopqrstuvwxyz"))
  (subseq string 12)
  => "mnopqrstuvwxyz"
  (subseq string 12 14)
  => "mn"

  (setf (subseq string 24) "qwer")
  string
  => "abcdefghijklmnopqrstuvwxqw"	; doesn't extend string
  (setf (subseq string 22) "asdf")
  => "abcdefghijklmnopqrstuvasdf"
You can use mapcar to slice a string up by character:
  (setf string "abcdefghijklmnopqrstuvwxyz")
  (mapcar (lambda (i) (char string i))
	  '(3 4 5 12 0 2 17 14))
  => (#\d #\e #\f #\m #\a #\c #\r #\o)
  (mapcar (lambda (i) (subseq string i (1+ i)))
	  '(3 4 5 12 0 2 17 14))
  => ("d" "e" "f" "m" "a" "c" "r" "o")
or by ofsets and lengths (this is vaguely similar to Perl's "unpack" function):
  (mapcar (lambda (i) (subseq string (first i) (+ (first i) (second i))))
	  '((4 2) (5 3) (6 4)))
  => ("ef" "fgh" "ghij")
  (apply #'concatenate 'string
	 (mapcar (lambda (i) (subseq string (first i) (+ (first i) (second i))))
		 '((4 2) (5 3) (6 4))))
  => "effghghij"
Exchange the first and last characters in a string:
  (defparameter string (copy-seq "make a hat"))
  (rotatef (char string 0) (char string (1- (length string))))
  string
  => "take a ham"
Just a few thoughts before bedtime. :) (Inspired by / adapted from the Perl Cookbook, 1.1, "Accessing Substrings".) -- Larry

Concatenating Strings

It's not immediately obvious how to concatenate strings to one another, because the general-purpose CONCATENATE function works on any sequence type. When using CONCATENATE, you have to specify the output type you want as the first argument:

(let ((a "one") (b "two") (c "three"))
  (concatenate 'string a b c))
=> "onetwothree"

-Stuart Sierra


This page is linked from:

Potting Soil