(define string "\\n") ; two characters, \ and an n (define string "\n") ; a "newline" character (define string "Jon \"Maddog\" Orwant") ; literal double quotes (define string "Jon 'Maddog' Orwant") ; literal single quotes (define a "This is a multiline here document terminated by a closing double quote") |
;; Use substring (substring str start end) (substring str start) ;; You can fill portions of a string with another string (substring-move-right! str start end newstring newstart) (substring-move-left! str start end newstring newstart) ;; Guile has a separate character type, and you can treat strings as a ;; character array. (string-ref str pos) (string-set! str pos char) (string-fill! str char) (substring-fill! str start end char) (define s "This is what you have") (define first (substring s 0 1)) ; "T" (define start (substring s 5 7)) ; "is" (define rest (substring s 13)) ; "you have" (define last (substring s (1- (string-length s)))) ; "e" (define end (substring s (- (string-length s) 4))) ; "have" (define piece (let ((len (string-length s))) (substring s (- len 8) (- len 5)))) ; "you" ;;; Or use the string library SRFI-13 (use-modules (srfi srfi-13)) (define s "This is what you have") (define first (string-take s 1)) ; "T" (define start (xsubstring s 5 7)) ; "is" (define rest (xsubstring s 13 -1)) ; "you have" (define last (string-take-right s 1)) ; "e" (define end (string-take-right s 4)) ; "have" (define piece (xsubstring s -8 -5)) ; "you" ;; Mutation of different sized strings is not allowed. You have to ;; use set! to change the variable. (set! s (string-replace s "wasn't" 5 7)) ;; This wasn't what you have (set! s (string-replace s "ondrous" 13 25)) ;; This wasn't wondrous (set! s (string-take-right s (1- (string-length s)))) ;; his wasn't wondrous (set! s (string-take s 9)) |
(define a (or b c)) (define a (if (defined? b) b c)) (define a (or (and (defined? b) b) c)) |
;; This doesn't really make sense in Scheme... temporary variables are ;; a natural construct and cheap. If you want to swap variables in a ;; block without introducing any new variable names, you can use let: (let ((a b) (b a)) ;; ... ) (let ((alpha beta) (beta production) (production alpha)) ;; ... ) |
(define num (char->integer char)) (define char (integer->char num)) (use-modules (srfi srfi-13)) (let ((str "sample")) (display (string-join (map number->string (map char->integer (string->list str))) " ")) (newline)) (let ((lst '(115 97 109 112 108 101))) (display (list->string (map integer->char lst))) (newline)) (letrec ((next (lambda (c) (integer->char (1+ (char->integer c)))))) (let* ((hal "HAL") (ibm (list->string (map next (string->list hal))))) (display ibm) (newline))) |
;; Convert the string to a list of characters (map proc (string->list str)) (use-modules (srfi srfi-1)) (format #t "unique chars are: ~A\n" (apply string (sort (delete-duplicates (string->list "an apple a day")) char<?))) (let* ((str "an apple a day") (sum (apply + (map char->integer (string->list str))))) (format #t "sum is ~A\n" sum)) ;;; or use string-fold/string-map/string-for-each from SRFI-13 (use-modules (srfi srfi-13)) (let* ((str "an apple a day") (sum (string-fold (lambda (c acc) (+ acc (char->integer c))) 0 str))) (format #t "sum is ~A\n" sum)) #!/usr/local/bin/guile -s !# ;; sum - compute 16-bit checksum of all input files (use-modules (srfi srfi-13)) (define (checksum p) (let loop ((line (read-line p 'concat)) (sum 0)) (if (eof-object? line) (format #t "~A ~A\n" sum (port-filename p)) (let ((line-sum (string-fold (lambda (c acc) (+ acc (char->integer c))) 0 line))) (loop (read-line p 'concat) (modulo (+ sum line-sum) (1- (expt 2 16)))))))) (let ((args (cdr (command-line)))) (if (null? args) (checksum (current-input-port)) (for-each (lambda (f) (call-with-input-file f checksum)) args))) #!/usr/local/bin/guile -s !# ;; slowcat - emulate a s l o w line printer (use-modules (ice-9 regex) (srfi srfi-2) (srfi srfi-13)) (define args (cdr (command-line))) (define delay 1) (and-let* ((p (pair? args)) (m (string-match "^-([0-9]+)$" (car args)))) (set! delay (string->number (match:substring m 1))) (set! args (cdr args))) (define (slowcat p) (let loop ((line (read-line p 'concat))) (cond ((not (eof-object? line)) (string-for-each (lambda (c) (display c) (usleep (* 5 delay))) line) (loop (read-line p 'concat)))))) (if (null? args) (slowcat (current-input-port)) (for-each (lambda (f) (call-with-input-file f slowcat)) args)) |
(define revbytes (list->string (reverse (string->list str)))) ;;; Or from SRFI-13 (use-modules (srfi srfi-13)) (define revbytes (string-reverse str)) (string-reverse! str) ; modifies in place (define revwords (string-join (reverse (string-tokenize str)) " ")) (with-input-from-file "/usr/share/dict/words" (lambda () (do ((word (read-line) (read-line))) ((eof-object? word)) (if (and (> (string-length word) 5) (string=? word (string-reverse word))) (write-line word))))) ;; A little too verbose on the command line ;; guile --use-srfi=13 -c ;; '(with-input-from-file "/usr/share/dict/words" ;; (lambda () (do ((word (read-line) (read-line))) ((eof-object? word)) ;; (if (and (> (string-length word) 5) (string=? word (string-reverse word))) ;; (write-line word)))))' |
;; Use regexp-substitute/global (regexp-substitute/global #f "([^\t]*)(\t+)" str (lambda (m) (let* ((pre-string (match:substring m 1)) (pre-len (string-length pre-string)) (match-len (- (match:end m 2) (match:start m 2)))) (string-append pre-string (make-string (- (* match-len 8) (modulo pre-len 8)) #\space)))) 'post) |
;; just interpolate $abc in strings: (define (varsubst str) (regexp-substitute/global #f "\\$(\\w+)" str 'pre (lambda (m) (eval (string->symbol (match:substring m 1)) (current-module))) 'post)) ;; interpolate $abc with error messages: (define (safe-varsubst str) (regexp-substitute/global #f "\\$(\\w+)" str 'pre (lambda (m) (catch #t (lambda () (eval (string->symbol (match:substring m 1)) (current-module))) (lambda args (format #f "[NO VARIABLE: ~A]" (match:substring m 1))))) 'post)) ;; interpolate ${(any (scheme expression))} in strings: (define (interpolate str) (regexp-substitute/global #f "\\${([^{}]+)}" str 'pre (lambda (m) (eval-string (match:substring m 1))) 'post)) |
(use-modules (srfi srfi-13)) (string-upcase "bo beep") ; BO PEEP (string-downcase "JOHN") ; john (string-titlecase "bo") ; Bo (string-titlecase "JOHN") ; John (string-titlecase "thIS is a loNG liNE") ; This Is A Long Line #!/usr/local/bin/guile -s !# ;; randcap: filter to randomly capitalize 20% of the time (use-modules (srfi srfi-13)) (seed->random-state (current-time)) (define (randcap p) (let loop ((line (read-line p 'concat))) (cond ((not (eof-object? line)) (display (string-map (lambda (c) (if (= (random 5) 0) (char-upcase c) (char-downcase c))) line)) (loop (read-line p 'concat)))))) (let ((args (cdr (command-line)))) (if (null? args) (randcap (current-input-port)) (for-each (lambda (f) (call-with-input-file f randcap)) args))) |
;; You can do this with format. Lisp/Scheme format is a little ;; different from what you may be used to with C/Perl style printf ;; (actually far more powerful) , but if you keep in mind that we use ;; ~ instead of %, and , instead of . for the prefix characters, you ;; won't have trouble getting used to Guile's format. (format #f "I have ~A guanacos." n) |
(define var " your text goes here") (use-modules (ice-9 regexp)) (set! var (regexp-substitute/global #f "\n +" var 'pre "\n" 'post)) (use-modules (srfi srfi-13)) (set! var (string-join (map string-trim (string-tokenize var #\newline)) "\n")) (use-modules (ice-9 regexp) (srfi srfi-13) (srfi srfi-14)) (define (dequote str) (let* ((str (if (char=? (string-ref str 0) #\newline) (substring str 1) str)) (lines (string-tokenize str #\newline)) (rx (let loop ((leader (car lines)) (lst (cdr lines))) (cond ((string= leader "") (let ((pos (or (string-skip (car lines) char-set:whitespace) 0))) (make-regexp (format #f "^[ \\t]{1,~A}" pos) regexp/newline))) ((null? lst) (make-regexp (string-append "^[ \\t]*" (regexp-quote leader)) regexp/newline)) (else (let ((pos (or (string-prefix-length leader (car lst)) 0))) (loop (substring leader 0 pos) (cdr lst)))))))) (regexp-substitute/global #f rx str 'pre 'post))) |
(use-modules (srfi srfi-13)) (define text "Folding and splicing is the work of an editor, not a mere collection of silicon and mobile electrons!") (define (wrap str max-col) (let* ((words (string-tokenize str)) (all '()) (first (car words)) (col (string-length first)) (line (list first))) (for-each (lambda (x) (let* ((len (string-length x)) (new-col (+ col len 1))) (cond ((> new-col max-col) (set! all (cons (string-join (reverse! line) " ") all)) (set! line (list x)) (set! col len)) (else (set! line (cons x line)) (set! col new-col))))) (cdr words)) (set! all (cons (string-join (reverse! line) " ") all)) (string-join (reverse! all) "\n"))) (display (wrap text 20)) |
(define str "Mom said, \"Don't do that.\"") (set! str (regexp-substitute/global #f "['\"]" str 'pre "\\" match:substring 'post)) (set! str (regexp-substitute/global #f "[^A-Z]" str 'pre "\\" match:substring 'post)) (set! str (string-append "this " (regexp-substitute/global #f "\W" "is a test!" 'pre "\\" match:substring 'post))) |
(use-modules (srfi srfi-13)) (define str " space ") (string-trim str) ; "space " (string-trim-right str) ; " space" (string-trim-both str) ; "space" |
(use-modules (srfi srfi-2) (srfi srfi-13) (ice-9 format)) (define parse-csv (let* ((csv-match (string-join '("\"([^\"\\\\]*(\\\\.[^\"\\\\]*)*)\",?" "([^,]+),?" ",") "|")) (csv-rx (make-regexp csv-match))) (lambda (text) (let ((start 0) (result '())) (let loop ((start 0)) (and-let* ((m (regexp-exec csv-rx text start))) (set! result (cons (or (match:substring m 1) (match:substring m 3)) result)) (loop (match:end m)))) (reverse result))))) (define line "XYZZY,\"\",\"O'Reilly, Inc\",\"Wall, Larry\",\"a \\\"glug\\\" bit,\",5,\"Error, Core Dumped\"") (do ((i 0 (1+ i)) (fields (parse-csv line) (cdr fields))) ((null? fields)) (format #t "~D : ~A\n" i (car fields))) |
(use-modules (srfi srfi-13) (srfi srfi-14)) ;; Knuth's soundex algorithm from The Art of Computer Programming, Vol 3 (define soundex (letrec ((chars "AEIOUYBFPVCGJKQSXZDTLMNR") (nums "000000111122222222334556") (skipchars (string->char-set "HW")) (trans (lambda (c) (let ((i (string-index chars c))) (if i (string-ref nums i) c))))) (lambda (str) (let* ((ustr (string-upcase str)) (f (string-ref ustr 0)) (skip (trans f))) (let* ((mstr (string-map trans (string-delete ustr skipchars 1))) (dstr (string-map (lambda (c) (cond ((eq? c skip) #\0) (else (set! skip c) c))) mstr)) (zstr (string-delete dstr #\0))) (substring (string-append (make-string 1 f) zstr "000") 0 4)))))) (soundex "Knuth") ; K530 (soundex "Kant") ; K530 (soundex "Lloyd") ; L300 (soundex "Ladd") ; L300 |
#!/usr/local/bin/guile -s !# (use-modules (srfi srfi-13) (srfi srfi-14) (ice-9 rw) (ice-9 regex)) (define data "analysed => analyzed built-in => builtin chastized => chastised commandline => command-line de-allocate => deallocate dropin => drop-in hardcode => hard-code meta-data => metadata multicharacter => multi-character multiway => multi-way non-empty => nonempty non-profit => nonprofit non-trappable => nontrappable pre-define => predefine preextend => pre-extend re-compiling => recompiling reenter => re-enter turnkey => turn-key") (define input (if (null? (cdr (command-line))) (current-input-port) (open-input-file (cadr (command-line))))) (let* ((newline-char-set (string->char-set "\n")) (assoc-char-set (string->char-set " =>")) (dict (map (lambda (line) (string-tokenize line assoc-char-set)) (string-tokenize data newline-char-set))) (dict-match (string-join (map car dict) "|"))) (let loop ((line (read-line input))) (cond ((not (eof-object? line)) (regexp-substitute/global (current-output-port) dict-match line 'pre (lambda (x) (cadr (assoc (match:substring x 0) dict))) 'post) (loop (read-line input 'concat)))))) (close-port input) |