Part 2: Core Programming Concepts
8. Strings & Text Processing
Working with text
A string is a sequence of characters — letters, digits, spaces, punctuation — treated as a single value. Text is everywhere in software: names, messages, file contents, web pages, user input. Knowing how to pick strings apart and reassemble them is one of the most practical everyday skills.
Characters and indexing
A string behaves much like the array from the previous chapter: each character sits at a zero-based index, and the string has a length. You can read a single character by its position, and reach the last character at index length − 1.
word = "HELLO"
print(word[0]) # 'H' (first character)
print(word[4]) # 'O' (last)
print(len(word)) # 5
Concatenation: joining strings
Putting strings together end-to-end is called concatenation, usually written with +. Remember that + means "add" for numbers but "join" for strings — and you cannot mix the two without converting, because "Age: " + 30 is an error, while "Age: " + str(30) works.
first = "Ada"
last = "Lovelace"
full = first + " " + last # "Ada Lovelace"
label = "Age: " + str(30) # convert the number first
Slicing: taking a piece
A slice extracts a substring by giving a start and end position. As with ranges, the start is included and the end is excluded, so word[0:3] gives the first three characters.
word = "programming"
print(word[0:4]) # "prog" (indices 0,1,2,3)
print(word[4:]) # "ramming" (from 4 to the end)
Common operations
Languages provide a rich toolkit for text. The names vary slightly, but the ideas are universal:
| Operation | Meaning | Example | Result |
|---|---|---|---|
| length | Number of characters | len("cat") | 3 |
| upper / lower | Change case | "cat".upper() | "CAT" |
| replace | Swap one piece for another | "a-b".replace("-", ":") | "a:b" |
| split | Break into a list on a separator | "a,b,c".split(",") | ["a","b","c"] |
| strip | Trim surrounding whitespace | " hi ".strip() | "hi" |
| find / index | Locate a substring | "hello".find("ll") | 2 |
Immutability
In many languages strings are immutable: operations like upper() or replace() do not change the original string — they return a new one. If you want to keep the result, assign it to a variable. Beginners often call a method and wonder why "nothing happened"; the answer is that the new string was thrown away because it was never stored.
name = "ada"
name.upper() # makes "ADA" but discards it
print(name) # still "ada"
name = name.upper() # now keep it
print(name) # "ADA"
Splitting and joining: a everyday pattern
A huge amount of real text work is "split a line into parts, process the parts, join them back." Reading a CSV line, parsing a date, or cleaning user input all follow this shape.
line = "Ada,36,London"
parts = line.split(",") # ["Ada", "36", "London"]
name = parts[0] # "Ada"
age = int(parts[1]) # 36
Key idea: strings are indexed sequences of characters; join them with concatenation, carve them with slicing, transform them with built-in operations, and remember that many string operations return new strings rather than changing the original.