Как использовать substring в Swift 4? Метод 'substring(to:)' устарел
Правильное извлечение подстрок в Swift 4
В Swift 4 и новее старые методы substring(to:), substring(from:) и substring(with:) действительно устарели. Вместо них используется универсальный синтаксис срезов (slicing) с помощью операторов частичного диапазона. Основная идея — работать с индексами String.Index и операторами ..<, ... и ..>.
Ключевые операторы частичного диапазона
..<upperBound— все символы до указанного индекса (не включая его).lowerBound...— все символы от указанного индекса до конца.lowerBound..<upperBound— диапазон между двумя индексами.
Решение вашей задачи
Вот как правильно получить подстроки из строки "Привет, мир!":
let fullString = "Привет, мир!"
// 1. Находим индекс запятой
if let commaIndex = fullString.firstIndex(of: ",") {
// 2. Получаем подстроку до запятой (без запятой)
let greeting = fullString[..<commaIndex] // "Привет"
print(greeting) // "Привет"
// 3. Получаем подстроку после запятой (пропускаем запятую и пробел)
let afterCommaStart = fullString.index(after: commaIndex) // индекс после запятой
let afterComma = fullString[afterCommaStart...] // " мир!"
print(afterComma) // " мир!"
// 4. Если нужно убрать пробел в начале после запятой:
let trimmedAfterComma = afterComma.trimmingCharacters(in: .whitespaces)
print(trimmedAfterComma) // "мир!"
}
Важные моменты
- Тип результата: Результат среза — это
Substring, а неString. Substring — это представление части исходной строки, которое использует её память. Для долгосрочного хранения преобразуйте вString:String(greeting). - Безопасность: Всегда проверяйте, что индекс найден (используйте
if letили guard). Не используйте force unwrap (!) — это может вызвать краш, если символ не найден. - Работа с Unicode: Swift корректно обрабатывает эмодзи, кириллицу и другие Unicode-символы. Индексы работают на уровне графемных кластеров, а не байтов.
Другие примеры
let text = "Swift 4.2"
// Первые 5 символов
let first5 = text.prefix(5) // "Swift"
print(first5)
// Последние 3 символа
let last3 = text.suffix(3) // "4.2"
print(last3)
// Срез с 6-го символа до конца
let startIndex = text.index(text.startIndex, offsetBy: 6)
let from6 = text[startIndex...] // "4.2"
print(from6)
// Срез с 6-го по 8-й символ (включая 8-й)
let endIndex = text.index(startIndex, offsetBy: 2)
let range = startIndex...endIndex
let middle = text[range] // "4.2"
print(middle)
Заключение
Новый синтаксис более явный и безопасный. Используйте String.Index для точного указания позиций и операторы диапазона для срезов. Не забывайте, что Substring — это временный тип; преобразуйте его в String, если планируете хранить долго.
Альтернативный подход: методы prefix и suffix
Если вам нужно просто взять первые N символов или последние N символов, можно использовать встроенные методы prefix(:) и suffix(:). Они работают с количеством символов, а не с индексами, что иногда удобнее.
let fullString = "Привет, мир!"
// Первые 6 символов (до запятой)
let greeting = fullString.prefix(6) // "Привет"
print(greeting)
// Последние 5 символов (после запятой и пробела)
let world = fullString.suffix(5) // "мир!"
print(world)
Недостаток: Этот способ требует точного знания количества символов. Если строка меняется динамически, лучше использовать поиск индекса, как показано в основном ответе. Также prefix и suffix возвращают Substring, поэтому при необходимости преобразуйте в String.
Для более сложных срезов (например, "с 3-го по 10-й символ") без индексов не обойтись — используйте index(_:offsetBy:).