Strings, Symbols & Characters
Everything you learned about sequenceable collections works on strings:
22.1 Strings are collections of characters
Everything you learned about sequenceable collections works on strings:
'hello' size. "→ 5"
'hello' first. "→ $h"
'hello' at: 2. "→ $e"
'hello' reversed. "→ 'olleh'"
'hello' asUppercase. "→ 'HELLO'"
'hello' collect: [ :c | c asUppercase ]. "→ 'HELLO'"
'hello world' select: [ :c | c isVowel ]. "→ 'eoo'"
'hello' includes: $l. "→ true"
'hello' occurrencesOf: $l. "→ 2"
'hello' asSet size. "→ 4"
'hello' asSymbol. "→ #hello"
'hello' , ' ' , 'world'. "→ 'hello world' (concatenation with ,)"22.2 Common string operations (Pharo)
'Hello World' includesSubstring: 'World'. "→ true"
'Hello World' beginsWith: 'Hello'. "→ true (also endsWith:)"
'a,b,,c' substrings: ','. "→ #('a' 'b' 'c') (empty fields dropped)"
'the quick brown fox' substrings. "→ #('the' 'quick' 'brown' 'fox')"
'line1
line2' lines. "→ #('line1' 'line2')"
' padded ' trimBoth. "→ 'padded'"
'hello' copyReplaceAll: 'll' with: 'LL'. "→ 'heLLo'"
'hello' capitalized. "→ 'Hello'"
'42' asNumber + 1. "→ 43"
'abc' sameAs: 'ABC'. "→ true (case-insensitive)"
'Hello {1}, you are {2}' format: { 'Ada' . 36 }. "→ 'Hello Ada, you are 36'"
'Hello {name}' format: { #name -> 'Bob' } asDictionary.
'héllo' utf8Encoded. "→ a ByteArray with UTF-8 bytes"
#[104 105] utf8Decoded. "→ 'hi'"
String new: 3 withAll: $z. "→ 'zzz'"
'tab' , String tab , 'separated'. "also String cr, String crlf, String space"22.3 Building strings efficiently
Repeated , copies the string each time. Use a stream:
String streamContents: [ :stream |
1 to: 5 do: [ :i | stream print: i ] separatedBy: [ stream nextPutAll: ', ' ] ].
"→ '1, 2, 3, 4, 5'"
String streamContents: [ :s | s << 'Total: ' << 42 printString; cr ].
(#('a' 'b' 'c') inject: '' into: [ :acc :e | acc , e ]). "fine for small inputs"
', ' join: #('a' 'b' 'c'). "→ 'a, b, c'"22.4 Mutability
Strings are mutable (except literals in recent Pharo, which are read-only):
| s |
s := 'hello' copy.
s at: 1 put: $j.
s. "→ 'jello'"22.5 Symbols
A Symbol is a unique, immutable string — two symbols with the same characters are the *same object*:
Use symbols for selectors, dictionary keys that are identifiers, states (#open, #closed), and options.
#foo == #foo. "→ true"
'foo' asSymbol == #foo. "→ true"
#foo size. "→ 3"
#at:put: numArgs. "→ 2"
#foo , 'bar'. "→ 'foobar' (a String)"
#+ isBinary. "→ true (Pharo)"
3 perform: #factorial. "→ 6 — symbols name messages (Chapter 30)"22.6 Characters
Pharo strings are Unicode: ByteString for Latin-1 content, WideString automatically when needed.
$a isVowel. $a isLetter. $5 isDigit. $ isSeparator.
$a asUppercase. $a asInteger. 97 asCharacter. $a value. "→ 97"
$5 digitValue. "→ 5"
Character value: 955. "→ λ (Unicode)"
Character cr. Character lf. Character tab. Character space. Character null.
$a < $b. ($a to: $e) asArray. "→ #($a $b $c $d $e)"22.7 Regular expressions
Pharo includes Vassili Bykov's regex package:
'hello world' matchesRegex: 'h.*d'. "→ true"
'a1b22c333' allRegexMatches: '\d+'. "→ an OrderedCollection('1' '22' '333')"
'2026-10-25' copyReplacingAllRegex: '-' with: '/'. "→ '2026/10/25'"
| m |
m := '(\w+)@(\w+)\.com' asRegex.
(m search: 'mail [email protected] now') ifTrue: [ m subexpression: 2 ]. "→ 'ada'"
'*.txt' match: 'notes.txt'. "→ true — glob-style matching"