PHP substr() Equivalent in Python

Python's slice syntax (`s[start:stop]`) replaces PHP's substr(), but PHP's third argument is a length while Python's second index is an end position — a common source of off-by-one mistakes when porting.

Close equivalent Covers the common case, but has documented behavioral differences.

PHP source
substr()
Closest Python API
slice syntax (str[start:stop])

Main limitation: PHP's `substr($str, $start, $length)` third argument is a *length* (how many characters to take); Python's `s[start:stop]` second index is an *end position* (exclusive) — `substr($s, 2, 3)` (3 characters starting at index 2) is `s[2:5]` in Python, not `s[2:3]`.

How to use each function

Before comparing the two, here's how substr() and slice syntax (str[start:stop]) work on their own.

PHP: substr()

substr(string $string, int $offset, ?int $length = null): string

Extracts a portion of a string starting at $offset (negative counts from the end) and continuing for $length characters (negative trims that many characters off the end instead). Never raises an error for out-of-range offsets — it returns an empty or truncated string instead.

Returns: The extracted substring.

PHP
substr("hello world", 6, 5); // "world"
substr("hello world", -5); // "world"

Python: slice syntax (str[start:stop])

s[start:stop:step]

Extracts a substring using Python's general slicing syntax. stop is an end position (exclusive), not a length like PHP's substr() third argument — to take n characters starting at start, use s[start:start+n]. Negative indices count from the end, and out-of-range indices never raise an error.

Returns: The extracted substring.

Python
"hello world"[6:11]  # 'world'
"hello world"[-5:]   # 'world'

Quick mapping

PHP substr()
Closest Python API slice syntax (str[start:stop])

How it differs

  • PHP's substr($str, $start, $length) third argument is a *length* (how many characters to take); Python's s[start:stop] second index is an *end position* (exclusive) — substr($s, 2, 3) (3 characters starting at index 2) is s[2:5] in Python, not s[2:3].
  • Both languages support negative indices to count from the end of the string, and the negative-index semantics line up well between PHP's substr() and Python's slicing — this is one of the more forgiving parts of the translation.
  • PHP's substr() never throws for out-of-range indices, silently returning an empty string or a truncated result instead; Python's slicing has the exact same forgiving behavior, so this edge case matches cleanly.

Examples

Basic substring by length

PHP
substr("hello world", 6, 5);
// "world"
Python
"hello world"[6:11]
# 'world'
PHP's length (5) becomes Python's end index (6 + 5 = 11) — always add the start and length together to get the Python stop index.

Negative start (from the end)

PHP
substr("hello world", -5);
// "world"
Python
"hello world"[-5:]
# 'world'
Negative start indices behave the same way in both languages — take everything from that position to the end.

Edge cases

Edge case

A negative length in PHP's substr($str, $start, $length) means "stop that many characters from the end", not "take |length| characters" — the Python equivalent is s[start:-abs(length)], which is easy to get backwards.

Edge case

Passing a start index beyond the string's length returns "" in PHP and '' in Python — both fail gracefully rather than raising an error.

References

  • PHP Manual — substr — checked 2026-07-29
  • Python docs — Sequence Types — string slicing (v3.x) — checked 2026-07-29

Last verified 2026-07-29.