Avatar ·

Как использовать substring в Swift 4? Метод 'substring(to:)' устарел

Всем привет! Я только начал изучать Swift 4 и столкнулся с проблемой при работе со строками. Раньше я видел в старых туториалах, что можно использовать метод `substring(to:)` для получения подстроки, но в Xcode 9 и Swift 4 этот метод помечен как deprecated. Вот пример кода, который я пытаюсь написать: ```swift let fullString = "Привет, мир!" let index = fullString.index(of: ",") let greeting = fullString.substring(to: index!) ``` Xcode выдает предупреждение: `'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator`. Я гуглил, но не совсем понимаю, как правильно использовать "строковый срез" (slicing subscript) с оператором `partial range from`. Можете объяснить на простом примере? Мне нужно получить подстроку до запятой, то есть слово "Привет" (без запятой и пробела). Также хотелось бы узнать, как получить подстроку после запятой — " мир!". Заранее спасибо за помощь! <<>>

Правильное извлечение подстрок в 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:).