1. Strings

Introduction

! -----------------------------
: string ( -- str ) "\\n" ;                 ! two characters, \ and an n
: string ( -- str ) "Jon 'Maddog' Orwant" ; ! literal single quotes
! -----------------------------
: string ( -- str ) "\n" ;                      ! a "newline" character
: string ( -- str ) "Jon \"Maddog\" Orwant" ;   ! literal double quotes
! -----------------------------
! Multiline strings need the multiline vocabulary

USE: multiline

STRING: a
This is a multiline document
terminated by ; on a line by itself
;

: a ( -- str )
    <" This is a multiline document
terminated by double quotes plus greater sign"> ;
! -----------------------------

Accessing Substrings

! -----------------------------
! use subseq from the sequences vocabulary, since strings are just sequences
from to str subseq

1 3 "abcdefg" subseq .
! "bc"

! The rest from a given position is handled by tail
str n tail

1 "abcdefg" tail .
! "bcdefg"

! Replacing a substring with replace-slice
newstr from to str replace-slice

"1234" 3 7 "abcdefg" [ replace-slice ] keep .
!"abc1234"

: replace-tail ( new from seq -- )
    dup length swap [ replace-slice ] keep ;

"1234" 3 "abcdefg" replace-tail .
! "abc1234"

! -----------------------------

! split at five character boundaries
USE: splitting
5 group     ! Splits sequence/string on top of stack into an array

"abcdefghijklmnopqrstuvwxyz" 5 group .
! { "abcde" "fghij" "klmno" "pqrst" "uvwxy" "z" }

! chop string into individual characters
1 group

"abcd" 1 group .
! { "a" "b" "c" "d" }

! -----------------------------
: str ( -- str ) "This is what you have" ;
!                +012345678901234567890  Indexing forwards  (left to right)
!                 109876543210987654321- Indexing backwards (right to left)
!                  note that 0 means 10 or 20, etc. above

0 1 str subseq  ! "T" (on top of stack)
str 1 head      ! "T"
5 7 str subseq  ! "is"
str 13 tail     ! "you have"
str 1 tail*     ! "e"
str 4 tail*     ! "have"
! 8 indexed from backward, 3 characters
str length 8 - dup 3 + str subseq   ! "you"
! Or with a new word, using the locals vocabulary
USE: locals
:: chars-from-rindex ( from count str -- newstr )
    str length from - dup count + str subseq ;

8 3 str chars-from-rindex   ! "you"

! -----------------------------
SYMBOL: str
"This is what you have" str set

str get print
! This is what you have

str get
! Top of stack: "This is what you have"

[ 5 head ] [ 7 tail ] bi "wasn't" swap 3append   ! change "is" to "wasn't"
! Top of stack: "This wasn't what you have"

13 head "ondrous" append    ! replace last 12 characters
! Top of stack: "This wasn't wondrous"

1 tail      ! delete first character
! Top of stack: "his wasn't wondrous"

10 head*    ! delete last 10 characters
! Top of stack: "his wasn'"

str set
! str = "his wasn'"

str get print
! his wasn'
! -----------------------------
! you can test substrings with "subseq?"

10 tail* "substring" swap subseq?
    [ "\"substring\" within the last 10 characters" print ]
    when

! substitute "at" for "is", restricted to first five characters
USING: peg peg.search ;

5 cut >r "is" token [ drop "at" ] action replace r> append

! -----------------------------
! exchange the first and last letters in a string
"make a hat"
1 cut 1 cut* spin 3append
print
! take a ham

! -----------------------------

Establishing a Default Value

Exchanging Values Without Using Temporary Variables

! -----------------------------
swap
! -----------------------------

Converting Between ASCII Characters and Values

Processing a String One Character at a Time

Reversing a String by Word or Character

Expanding and Compressing Tabs

Expanding Variables in User Input

Controlling Case

Interpolating Functions and Expressions Within Strings

Indenting Here Documents

Reformatting Paragraphs

Escaping Characters

Trimming Blanks from the Ends of a String

Parsing Comma-Separated Data

! -----------------------------
! The "csv" vocabulary allows to parse real CSV

! reading the file "testdata.csv", UTF-8 encoded, CSV format
USE: csv

"testdata.csv" utf8 <file-reader> csv
! An array of row arrays is on the top of the stack now.

! -----------------------------
! You could use the word "<string-reader>" to turn a string into a stream.

USING: csv io.streams.string ;

"XYZZY,\"\",\"O'Reilly, Inc\",\"Wall, Larry\",\"a \"\"glug\"\" bit,\",5,\"Error, Core Dumped\""
    <string-reader> csv .
!    {
!        {
!            "XYZZY"
!            ""
!            "O'Reilly, Inc"
!            "Wall, Larry"
!            "a \"glug\" bit,"
!            "5"
!            "Error, Core Dumped"
!        }
!    }
! -----------------------------

Soundex Matching

Program: fixstyle

Program: psgrep