str#

str is immutable Unicode. The operator’s most-touched data type. Six literal forms, an extensive method surface, slicing, and f-strings with a format spec mini-language. Mixing with bytes always requires an explicit encode or decode.

Quoting and escapes#

Single, double, and triple-quoted strings are identical aside from what they can contain without escaping.

s   = "hello"
s2  = 'also fine'             # single quotes equivalent
ml  = """multi
line"""                       # newlines preserved
r   = r"\n is literal"        # raw: backslash is not an escape
esc = "tab\there, newline\n"  # \t \n \xNN \uNNNN \UNNNNNNNN

Raw strings (r"...") are the default for regex patterns, Windows paths, and anywhere a backslash should mean itself.

f-strings and format spec#

f-strings are the default. The = self-debug form and the format spec mini-language cover most needs. Examples assume n, pi = 42, 3.14159 and y = ... for the conversion forms.

Form

Example

Result

Plain

f"{n}"

"42"

Width, right-align

f"{n:5}"

"   42"

Width, left-align

f"{n:<5}"

"42   "

Zero-pad

f"{n:05}"

"00042"

Explicit fill + align

f"{n:0>5}"

"00042"

Hex

f"{n:x}"

"2a"

Binary

f"{n:b}"

"101010"

Fixed-point

f"{pi:.2f}"

"3.14"

Scientific

f"{pi:10.3e}"

" 3.142e+00"

Thousands separator

f"{1e6:,}"

"1,000,000"

Percent

f"{0.85:.1%}"

"85.0%"

Self-debug

f"{n=}"

"n=42"

!r conversion

f"{y!r}"

repr(y)

!s conversion

f"{y!s}"

str(y)

!a conversion

f"{y!a}"

ascii(y)

Datetime values format with their own strftime codes. Examples assume t = datetime(2026, 5, 19, 14, 35).

Code

Example

Result

%Y-%m-%d

f"{t:%Y-%m-%d}"

"2026-05-19"

%H:%M

f"{t:%H:%M}"

"14:35"

Format spec syntax: [fill][align][sign][#][0][width][,][.precision][type]. align is < left, > right, ^ centre, = for numeric sign-fill. type is the conversion (s string, d int, f float, e scientific, x hex, b binary, o octal, % percent).

Methods#

The operator’s daily kit on str. Examples below assume s = "  Hello, Operator  ".

Method

Example

Effect

strip

s.strip()

"Hello, Operator"; trim leading and trailing whitespace.

lstrip

s.lstrip()

Trim leading whitespace only.

rstrip

s.rstrip()

Trim trailing whitespace only.

lower

s.lower()

Lowercase.

upper

s.upper()

Uppercase.

title

s.title()

Title case.

casefold

s.casefold()

Aggressive lowercase for caseless comparison.

split

s.split(", ")

Split on ", " into a list.

rsplit

s.rsplit(maxsplit=1)

Right-to-left split with a cap on splits.

join

", ".join(["a", "b", "c"])

Concatenate an iterable of strings with a separator.

replace

s.replace("Operator", "World")

Replace every occurrence; pass a count to cap.

startswith

s.startswith("  Hello")

Prefix test; accepts a tuple of prefixes.

endswith

s.endswith("  ")

Suffix test; accepts a tuple of suffixes.

find

s.find("Op")

First index of substring or -1.

index

s.index("Op")

First index of substring; raises ValueError if missing.

count

s.count(" ")

Non-overlapping occurrence count.

len

len(s)

Character count (built-in, not a method).

zfill

s.zfill(10)

Left-pad with 0 to width.

center

s.center(20, "-")

Centre-pad to width with a fill char.

ljust

s.ljust(20)

Left-justify to width.

translate

"hello world".translate(str.maketrans("ao", "@0"))

Per-character substitution via a translation table.

Slicing#

The other half of string work. Examples assume s = "abcdefg".

Form

Example

Result

Index

s[0]

'a'

Negative index

s[-1]

'g'

Range slice

s[1:4]

'bcd'

Stride

s[::2]

'aceg'

Reverse

s[::-1]

'gfedcba'

Building#

Build long strings with join over a sequence, not by repeated += in a loop. += allocates a new string each time; join walks once and concatenates into a single buffer.

"-".join(parts)                       # one allocation
"".join(f"<{tag}>{v}</{tag}>" for tag, v in fields)

When the parts arrive incrementally (a streaming writer, a recursive walk), use io.StringIO as an accumulator and call getvalue() at the end.

import io
buf = io.StringIO()
buf.write("HEAD ")
buf.write(path)
buf.write(" HTTP/1.1\r\n")
wire = buf.getvalue()

Regex#

re is the stdlib regex engine. Compile patterns once when they’re reused; named groups make extraction readable.

import re

IPV4 = re.compile(r"\b(?:\d{1,3}\.){3}\d{1,3}\b")
for line in lines:
    for ip in IPV4.findall(line):
        print(ip)

m = re.match(r"(?P<user>\w+)@(?P<host>[\w.-]+)", "op@example.com")
if m:
    print(m["user"], m["host"])

Method cheat sheet.

Call

Returns

re.match(p, s)

Match if pattern matches at the start, else None

re.search(p, s)

first Match anywhere, else None

re.fullmatch(p, s)

Match if the whole string matches

re.findall(p, s)

list of matched groups (or whole match if no groups)

re.finditer(p, s)

iterator of Match objects

re.sub(p, repl, s)

s with non-overlapping matches replaced

re.split(p, s)

s split at every match

re.compile(p)

reusable pattern object (use it for hot loops)

Flags.

Flag

Effect

re.IGNORECASE (re.I)

Case-insensitive match.

re.MULTILINE (re.M)

^ and $ match at every line boundary.

re.DOTALL (re.S)

. matches newline as well.

re.VERBOSE (re.X)

Free-spacing with inline comments.

The deeper regex surface (lookahead, backrefs, atomic groups, flavour differences across engines) lives in Regex.

Method catalog#

The complete instance-method surface on str, grouped by purpose.

Case#

Method

Effect

lower()

Lowercase using simple case folding.

upper()

Uppercase.

title()

Title case (capitalise each word).

capitalize()

Uppercase the first character; lowercase the rest.

swapcase()

Swap case of every character.

casefold()

Aggressive lowercase for caseless comparison.

Trim and pad#

Method

Effect

strip([chars])

Trim leading and trailing chars (whitespace by default).

lstrip([chars])

Trim leading chars only.

rstrip([chars])

Trim trailing chars only.

removeprefix(p)

Strip p from the start if present (3.9+).

removesuffix(s)

Strip s from the end if present (3.9+).

ljust(width, fill=' ')

Left-justify to width with a fill char.

rjust(width, fill=' ')

Right-justify to width.

center(width, fill=' ')

Centre to width.

zfill(width)

Left-pad with 0 to width (preserves leading sign).

expandtabs(tabsize=8)

Replace tabs with spaces.

Split and join#

Method

Effect

split(sep=None, maxsplit=-1)

Split on sep (or any whitespace if None).

rsplit(sep=None, maxsplit=-1)

Split from the right.

splitlines(keepends=False)

Split on universal newlines.

partition(sep)

Split into (head, sep, tail) at the first sep.

rpartition(sep)

Split at the last sep.

join(iterable)

Concatenate iterable of strings with this string between.

Search and replace#

Method

Effect

find(sub[, start[, end]])

Lowest index of sub or -1.

rfind(sub[, start[, end]])

Highest index of sub or -1.

index(sub[, start[, end]])

Like find but raises ValueError on miss.

rindex(sub[, start[, end]])

Like rfind but raises.

count(sub[, start[, end]])

Non-overlapping occurrence count.

startswith(prefix[, start[, end]])

Prefix test; accepts a tuple of prefixes.

endswith(suffix[, start[, end]])

Suffix test; accepts a tuple of suffixes.

replace(old, new[, count])

Replace occurrences; count caps replacements.

translate(table)

Per-character substitution via a str.maketrans table.

Predicates#

Method

True when

isalpha()

All characters are letters and string is non-empty.

isdigit()

All characters are digits.

isdecimal()

All characters are decimal digits.

isnumeric()

All characters are numeric (broader than isdigit).

isalnum()

All characters are alphanumeric.

isspace()

All characters are whitespace.

isascii()

All characters are ASCII.

islower()

All cased characters are lowercase.

isupper()

All cased characters are uppercase.

istitle()

Title-cased.

isidentifier()

Valid as a Python identifier.

isprintable()

Every character is printable.

Encoding and formatting#

Method

Effect

encode(encoding='utf-8', errors='strict')

Encode to bytes.

format(*args, **kwargs)

Legacy "{}".format interpolation.

format_map(mapping)

format taking a mapping instead of kwargs.

str.maketrans(x[, y[, z]])

Build a translation table for translate (staticmethod).

A few representative method examples; the full surface is too broad to walk through here.

split cuts on the first argument; rsplit with a maxsplit cap keeps the rest intact.

"a,b,c,d".rsplit(",", 1)
['a,b,c', 'd']

partition splits into a three-tuple at the first occurrence.

"key=value=extra".partition("=")
('key', '=', 'value=extra')

translate with a str.maketrans table substitutes character-by-character.

"hello".translate(str.maketrans("el", "3L"))
'h3LLo'

encode rounds to bytes; decode rounds back.

"café".encode("utf-8")
b'caf\xc3\xa9'

Operator overloading#

The dunder methods str implements.

Operator

Dunder

Returns

a + b

__add__

Concatenation.

a * n

__mul__

Repetition.

a == b

__eq__

Equality.

a < b

__lt__

Lexicographic less than.

hash(a)

__hash__

Hash for set / dict membership.

a in b

__contains__

Substring membership test.

a[i] / a[i:j]

__getitem__

Indexing and slicing.

len(a)

__len__

Character count.

iter(a)

__iter__

Character iteration.

f"{a:fmt}"

__format__

Format spec interpolation.

repr(a) / str(a)

__repr__ / __str__

Debug and human-readable forms.

bool(a)

__bool__

False only for the empty string.

A path class can use __truediv__ for / and __str__ for the rendered form (mirroring pathlib.Path).

class Path:
    def __init__(self, parts): self.parts = list(parts)
    def __truediv__(self, name): return Path(self.parts + [name])
    def __str__(self): return "/".join(self.parts)

str(Path(["var", "log"]) / "auth.log")
'var/log/auth.log'

__format__ lets a class participate in f-string format specs.

class Hex:
    def __init__(self, n): self.n = n
    def __format__(self, spec): return format(self.n, spec or "x")

f"{Hex(255)}, {Hex(255):08x}"
'ff, 000000ff'

References#