Swift Substring Using String Indices

To get a substring from a Swift String, create valid String.Index values for the start and end positions, form a range, and use that range to slice the string. Swift does not support direct integer subscripting such as str[2] because a visible character can contain more than one Unicode scalar.

Slicing a string returns a Substring. A Substring provides the same string operations as String, but it may share storage with the original string. Convert it to String when you need to store it for later use.

Swift Substring Range Syntax

The following syntax extracts characters after skipping startPosition characters from the beginning and endPosition characters from the end:

</>
Copy
let start = str.index(str.startIndex, offsetBy: startPosition)
let end = str.index(str.endIndex, offsetBy: -endPosition)
let range = start..<end

let subStr = str[range]

Here, startPosition is the number of characters skipped from the beginning of str. endPosition is the number of characters excluded from the end. The half-open range operator ..< includes the character at start and excludes the character at end.

Both offsets must produce indices inside the string, and the start index must not come after the end index. Invalid offsets cause a runtime error.

Convert a Swift Substring to String

The result of range-based slicing is a Substring. Use the String initializer when an API requires a String or when the extracted value will be retained independently.

</>
Copy
let text = "TutorialKart"
let start = text.index(text.startIndex, offsetBy: 2)
let end = text.index(text.startIndex, offsetBy: 8)

let slice = text[start..<end]
let result = String(slice)

print(result)

Output

torial

Swift Substring Examples with Start and End Offsets

This example demonstrates how to find the substring of a string. The starting position is 2, and 4 characters are excluded from the end.

main.swift

</>
Copy
var str = "TutorialKart"

let start = str.index(str.startIndex, offsetBy: 2)
let end = str.index(str.endIndex, offsetBy: -4)
let range = start..<end

let subStr = str[range]

print( subStr )

Output

torial

Swift Substring from the Beginning with startPosition 0

When startPosition is 0, the range starts at startIndex. In this example, four characters are removed from the end, so the result contains the first eight characters.

main.swift

</>
Copy
var str = "TutorialKart"

let start = str.index(str.startIndex, offsetBy: 0)
let end = str.index(str.endIndex, offsetBy: -4)
let range = start..<end

let subStr = str[range]

print( subStr )

Output

Tutorial

Swift Substring to the End with endPosition 0

When endPosition is 0, the end index is str.endIndex. The substring therefore begins at the specified start position and continues through the final character.

main.swift

</>
Copy
var str = "TutorialKart"

let start = str.index(str.startIndex, offsetBy: 5)
let end = str.index(str.endIndex, offsetBy: 0)
let range = start..<end

let subStr = str[range]

print( subStr )

Output

ialKart

Swift Substring Error When an Offset Exceeds String Length

An offset larger than the number of characters in the string does not produce a valid String.Index. The following example attempts to move 25 characters from the beginning of a 12-character string and therefore terminates with an out-of-bounds error.

main.swift

</>
Copy
var str = "TutorialKart"

let start = str.index(str.startIndex, offsetBy: 25)
let end = str.index(str.endIndex, offsetBy: 0)
let range = start..<end

let subStr = str[range]

print( subStr )

Output

Fatal error: String index is out of bounds: file Swift/StringCharacterView.swift, line 60
2021-02-12 09:30:02.489899+0530 HelloWorld[1072:40084] Fatal error: String index is out of bounds: file Swift/StringCharacterView.swift, line 60
Printing description of range:
▿ Range(Swift.String.Index(_rawBits: 0)..<Swift.String.Index(_rawBits: 0))
  ▿ lowerBound : Index
    - _rawBits : 0
  ▿ upperBound : Index
    - _rawBits : 0
(lldb) 

Safely Create Swift Substring Indices

Use index(_:offsetBy:limitedBy:) when an offset may come from user input or external data. It returns an optional index instead of moving beyond the supplied limit.

</>
Copy
let text = "TutorialKart"
let startOffset = 2
let endOffset = 8

if let start = text.index(
    text.startIndex,
    offsetBy: startOffset,
    limitedBy: text.endIndex
),
let end = text.index(
    text.startIndex,
    offsetBy: endOffset,
    limitedBy: text.endIndex
),
start <= end {
    let substring = text[start..<end]
    print(substring)
} else {
    print("Invalid substring range")
}

Output

torial

Swift prefix, suffix, dropFirst, and dropLast Alternatives

For common operations at either end of a string, Swift collection methods are shorter than creating a range manually:

</>
Copy
let text = "TutorialKart"

print(text.prefix(8))
print(text.suffix(4))
print(text.dropFirst(2))
print(text.dropLast(4))

Output

Tutorial
Kart
torialKart
Tutorial

These methods also return subsequences, so wrap the result in String(...) when a stored String value is required.

Swift Substring with Closed and Partial Ranges

A half-open range is common because its upper bound is excluded. Swift also supports partial ranges when a substring begins at the start of the string or continues to the end.

</>
Copy
let text = "TutorialKart"

let splitIndex = text.index(text.startIndex, offsetBy: 8)
let firstPart = text[..<splitIndex]
let secondPart = text[splitIndex...]

print(firstPart)
print(secondPart)

Output

Tutorial
Kart

Why Swift Strings Do Not Use Integer Indices

Swift models a string as a collection of extended grapheme clusters. A single displayed character can be represented by several Unicode scalars, so character boundaries are not guaranteed to be one byte apart. String.Index preserves valid character boundaries and prevents slicing through the middle of a character.

Swift Substring Questions

How do I get a substring by integer positions in Swift?

Convert each integer offset to a String.Index with index(_:offsetBy:), create a range from those indices, and subscript the string with that range.

What is the difference between String and Substring in Swift?

String owns its string storage. A Substring is a slice that can share storage with its source string. Use String(substring) when retaining the extracted text or passing it to code that requires String.

How do I get the first or last characters of a Swift String?

Use prefix(_:) for the first characters and suffix(_:) for the last characters. Both return subsequences.

How can I avoid a String index out-of-bounds error?

Validate offsets against string.count, or use index(_:offsetBy:limitedBy:) and handle the optional result before creating the range.

Swift Substring Summary

To extract part of a Swift string, calculate valid String.Index values and use a range such as start..<end. Use prefix, suffix, dropFirst, or dropLast for simpler edge-based slices, and convert the resulting Substring to String when necessary. Continue with this Swift Tutorial for more Swift string operations.