Strings & regular expressions
Customer names, phone numbers, invoice IDs and addresses all arrive as text, and they are rarely clean. Python's string methods handle most cleaning jobs; regular expressions handle the rest.
Everyday string methods
Strings are immutable, so every method returns a new string.
raw = " mumbai , MAHARASHTRA "
city, state = [part.strip().title() for part in raw.split(",")]
print(city, state) # Mumbai Maharashtra
print("INV-2026-0042".startswith("INV")) # True
print("9876543210".isdigit()) # True
print("-".join(["2026", "09", "22"])) # 2026-09-22
print("Chai".center(10, "*")) # ***Chai***
Formatting with f-strings
Format specifiers go after a colon inside the braces.
| Spec | Example | Output |
|---|---|---|
,.2f |
f"{1234567.5:,.2f}" |
1,234,567.50 |
>8 |
f"{'Ok':>8}" |
Ok |
% |
f"{0.183:.1%}" |
18.3% |
= (debug) |
f"{total=}" |
total=450 |
Note that , groups in thousands; Indian lakh/crore grouping needs custom code or the babel package.
Regular expressions with re
A regular expression is a mini-language for describing text patterns. Always write patterns as raw strings (r"...")
so backslashes reach the regex engine untouched.
| Pattern | Matches |
|---|---|
\d |
a digit |
\w |
letter, digit or underscore |
\s |
whitespace |
+ / * / ? |
one or more / zero or more / optional |
{10} |
exactly ten times |
^ / $ |
start / end of string |
( ) |
a capture group |
import re
text = "Call Priya on 98765 43210 or Arjun at +91-9123456780."
# Remove spaces and dashes, then find 10-digit Indian mobile numbers
digits = re.sub(r"[\s-]", "", text)
print(re.findall(r"(?:\+91)?([6-9]\d{9})", digits)) # ['9876543210', '9123456780']
# Validate a GSTIN-like code: 2 digits, 5 letters, 4 digits, letter, alnum, 'Z', alnum
gstin = re.compile(r"^\d{2}[A-Z]{5}\d{4}[A-Z][A-Z\d]Z[A-Z\d]$")
print(bool(gstin.match("27ABCDE1234F1Z5"))) # True
match, search, findall and named groups
re.matchchecks only at the start of the string.re.searchfinds the first match anywhere.re.findallreturns every match as a list.re.fullmatchrequires the whole string to match.
Named groups make results self-documenting:
m = re.search(r"(?P<day>\d{2})/(?P<month>\d{2})/(?P<year>\d{4})", "Delivered on 05/08/2026")
if m:
print(m["year"], m["month"], m["day"]) # 2026 08 05
Key takeaways
- Try string methods first; reach for
rewhen the pattern varies. - Always use raw strings for patterns and compile patterns you reuse.
re.matchreturnsNonewhen nothing matches, so check before using the result.- Regex is great for extracting and validating, but do not use it to parse HTML or JSON — use a proper parser.
Practice
Write a function extract_amounts(text) that returns all rupee amounts written like Rs. 1,250 or ₹499.50
as a list of floats. Test it on a short paragraph that contains at least four amounts in different formats.