Strings: Working with Text
Welcome! So far we’ve learned about numbers and lists. Now let’s learn about text - how computers handle words and sentences.
What is a String?
A string is just text. Like a sentence, a name, or a message.
Real Life Analogy:
- String = A necklace with beads
- Each character = One bead (letter, number, or symbol)
- The necklace = The whole piece of text
Creating Strings
Simple Text
// Basic strings
greeting := "Hello, World!"
name := "Alice"
empty := "" // Empty string (no beads)
// Multi-line strings (like a poem)
poem := `Roses are red
Violets are blue
Go is awesome
And so are you!`
Real Life Example:
// Like labeling boxes
box1 := "Books"
box2 := "Clothes"
box3 := "Toys"
fmt.Println("Box 1 contains:", box1)
fmt.Println("Box 2 contains:", box2)
fmt.Println("Box 3 contains:", box3)
Reading Strings
How Long is the Text?
message := "Hello!"
length := len(message) // length = 6
name := "Alice"
nameLength := len(name) // nameLength = 5
empty := ""
emptyLength := len(empty) // emptyLength = 0
Getting Individual Characters
word := "Hello"
// Get first letter
first := word[0] // 'H' (but as a number!)
// Get second letter
second := word[1] // 'e'
// Get last letter
last := word[4] // 'o'
Important: word[0] gives you a number (ASCII code), not the letter ‘H’. We’ll learn how to fix this.
Looping Through Characters
name := "Alice"
fmt.Println("Letters in", name + ":")
for i := 0; i < len(name); i++ {
fmt.Printf("Position %d: %c\n", i, name[i])
}
Output:
Letters in Alice:
Position 0: A
Position 1: l
Position 2: i
Position 3: c
Position 4: e
Combining Strings (Like Glueing Words Together)
Method 1: Using +
firstName := "John"
lastName := "Doe"
fullName := firstName + " " + lastName // "John Doe"
greeting := "Hello" + " " + "World" + "!" // "Hello World!"
Method 2: Building Step by Step
var message strings.Builder
message.WriteString("Hello")
message.WriteString(" ")
message.WriteString("World")
message.WriteString("!")
finalMessage := message.String() // "Hello World!"
Real Life Example: Building a Shopping List
package main
import "fmt"
func main() {
// Start building a list
var list strings.Builder
list.WriteString("Shopping List:\n")
list.WriteString("- Milk\n")
list.WriteString("- Bread\n")
list.WriteString("- Eggs\n")
fmt.Println(list.String())
}
Searching in Strings
Does it contain a word?
sentence := "I love programming in Go"
// Check if it contains "love"
hasLove := strings.Contains(sentence, "love") // true
// Check if it contains "Python"
hasPython := strings.Contains(sentence, "Python") // false
Where is a word?
text := "The cat sat on the mat"
// Find where "cat" starts
catPosition := strings.Index(text, "cat") // 4
// Find where "dog" starts (doesn't exist)
dogPosition := strings.Index(text, "dog") // -1
Starts or ends with?
filename := "document.txt"
// Does it start with "doc"?
startsWithDoc := strings.HasPrefix(filename, "doc") // true
// Does it end with ".txt"?
endsWithTxt := strings.HasSuffix(filename, ".txt") // true
// Does it end with ".pdf"?
endsWithPdf := strings.HasSuffix(filename, ".pdf") // false
Splitting and Joining Strings
Splitting (Breaking Apart)
// Split by comma
csv := "apple,banana,orange"
fruits := strings.Split(csv, ",") // ["apple", "banana", "orange"]
// Split by space
sentence := "The quick brown fox"
words := strings.Fields(sentence) // ["The", "quick", "brown", "fox"]
// Split by lines
poem := "Roses are red\nViolets are blue"
lines := strings.Split(poem, "\n") // ["Roses are red", "Violets are blue"]
Joining (Putting Together)
fruits := []string{"apple", "banana", "orange"}
// Join with commas
csv := strings.Join(fruits, ",") // "apple,banana,orange"
// Join with arrows
withArrows := strings.Join(fruits, " -> ") // "apple -> banana -> orange"
// Join with newlines
list := strings.Join(fruits, "\n") // "apple\nbanana\norange"
Real Life Example: Email List
package main
import (
"fmt"
"strings"
)
func main() {
// List of friends
friends := []string{"alice@example.com", "bob@example.com", "charlie@example.com"}
// Create email list
emailList := strings.Join(friends, "; ")
fmt.Println("Send to:", emailList)
// Output: Send to: alice@example.com; bob@example.com; charlie@example.com
}
Changing Case
Uppercase and Lowercase
text := "Hello World!"
// Make all uppercase
loud := strings.ToUpper(text) // "HELLO WORLD!"
// Make all lowercase
quiet := strings.ToLower(text) // "hello world!"
// Title case (first letter of each word capitalized)
title := strings.Title(text) // "Hello World!"
Real Life Examples
Example 1: Name Formatter
package main
import (
"fmt"
"strings"
)
func formatName(first, last string) string {
// Capitalize first letter of each name
first = strings.Title(strings.ToLower(first))
last = strings.Title(strings.ToLower(last))
// Combine with space
return first + " " + last
}
func main() {
// Test with messy input
name1 := formatName("john", "doe") // "John Doe"
name2 := formatName("MARY", "SMITH") // "Mary Smith"
name3 := formatName("aLiCe", "jOhNsOn") // "Alice Johnson"
fmt.Println(name1)
fmt.Println(name2)
fmt.Println(name3)
}
Example 2: Simple Search Engine
package main
import (
"fmt"
"strings"
)
func searchInText(text, query string) bool {
// Convert both to lowercase for case-insensitive search
text = strings.ToLower(text)
query = strings.ToLower(query)
return strings.Contains(text, query)
}
func main() {
document := "Go is a programming language created by Google. It's fast and simple."
// Search for different things
fmt.Printf("Contains 'go': %t\n", searchInText(document, "go"))
fmt.Printf("Contains 'python': %t\n", searchInText(document, "python"))
fmt.Printf("Contains 'FAST': %t\n", searchInText(document, "FAST"))
}
Output:
Contains 'go': true
Contains 'python': false
Contains 'FAST': true
Example 3: URL Parser
package main
import (
"fmt"
"strings"
)
func getDomain(url string) string {
// Remove http:// or https://
if strings.HasPrefix(url, "https://") {
url = url[8:] // Remove "https://"
} else if strings.HasPrefix(url, "http://") {
url = url[7:] // Remove "http://"
}
// Find first /
slashPos := strings.Index(url, "/")
if slashPos != -1 {
return url[:slashPos] // Take everything before /
}
return url // No / found, return whole thing
}
func main() {
urls := []string{
"https://www.google.com/search",
"http://github.com/user/repo",
"https://stackoverflow.com/questions",
}
for _, url := range urls {
domain := getDomain(url)
fmt.Printf("URL: %s -> Domain: %s\n", url, domain)
}
}
Output:
URL: https://www.google.com/search -> Domain: www.google.com
URL: http://github.com/user/repo -> Domain: github.com
URL: https://stackoverflow.com/questions -> Domain: stackoverflow.com
Common String Problems
Problem 1: Reverse a String
func reverseString(text string) string {
// Convert to rune slice (handles special characters)
runes := []rune(text)
// Swap characters from outside in
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}
// Test
original := "Hello"
reversed := reverseString(original) // "olleH"
Problem 2: Check if Palindrome
A palindrome reads the same forwards and backwards (like “racecar”)
func isPalindrome(text string) bool {
// Convert to lowercase and remove spaces
text = strings.ToLower(text)
text = strings.ReplaceAll(text, " ", "")
// Check if it equals its reverse
reversed := reverseString(text)
return text == reversed
}
// Test
fmt.Printf("racecar: %t\n", isPalindrome("racecar")) // true
fmt.Printf("hello: %t\n", isPalindrome("hello")) // false
fmt.Printf("A man a plan a canal Panama: %t\n", isPalindrome("A man a plan a canal Panama")) // true
Problem 3: Count Words
func countWords(text string) int {
// Split by spaces and count pieces
words := strings.Fields(text)
return len(words)
}
// Test
sentence := "The quick brown fox jumps over the lazy dog"
wordCount := countWords(sentence) // 9
Problem 4: Replace Words
func censorBadWords(text string) string {
// List of bad words
badWords := []string{"stupid", "dumb", "idiot"}
// Replace each bad word with stars
result := text
for _, badWord := range badWords {
stars := strings.Repeat("*", len(badWord))
result = strings.ReplaceAll(result, badWord, stars)
}
return result
}
// Test
message := "That movie was stupid and the plot was dumb"
clean := censorBadWords(message)
// "That movie was ****** and the plot was ****"
Practice Time!
Exercise 1: Email Validator
Create a function that checks if a string looks like an email address (contains @ and .)
Exercise 2: Password Strength Checker
Check if a password:
- Is at least 8 characters long
- Contains at least one uppercase letter
- Contains at least one number
Exercise 3: Word Counter
Count how many times each word appears in a sentence.
Exercise 4: Simple Translator
Replace English words with their Spanish equivalents:
- hello -> hola
- goodbye -> adios
- thank you -> gracias
Important Notes
Strings are Immutable
text := "Hello"
// You CANNOT do: text[0] = 'J' to change to "Jello"
// You must create a new string
Characters vs Bytes
text := "Hello"
fmt.Println(len(text)) // 5 bytes
text2 := "Hello 世界"
fmt.Println(len(text2)) // 11 bytes (5 ASCII + 6 for Chinese characters)
Use strings.Builder for Many Changes
// Bad (slow)
result := ""
for i := 0; i < 1000; i++ {
result += "word"
}
// Good (fast)
var builder strings.Builder
for i := 0; i < 1000; i++ {
builder.WriteString("word")
}
result := builder.String()
What’s Next?
Great job! You’ve learned about arrays, slices, and strings. These are your basic data structures. Next, we’ll move to more advanced structures like Linked Lists - where items are connected like a chain!
Quick Quiz
- What’s the difference between
len(text)and counting characters by hand? - How do you combine two strings?
- How do you check if text contains a word?
- How do you split “apple,banana,orange” into separate fruits?
- How do you reverse the string “hello”?
Remember: Strings are like sentences made of letters. Each letter has a position, and you can search, split, and combine them just like words in a book!