Как заменить символы в строке в Swift? (replace characters in String)
Замена символов в строке Swift: полное руководство
В Swift замена символов и подстрок выполняется несколькими способами. В отличие от Python или JavaScript, у строк Swift нет единого универсального метода replace(), но есть более гибкие и мощные инструменты. Рассмотрим все основные подходы.
1. Метод replacingOccurrences(of:with:)
Это основной и самый простой способ замены всех вхождений подстроки. Он возвращает новую строку, не изменяя исходную (строки в Swift — value types).
var text = "Hello World"
let replaced = text.replacingOccurrences(of: " ", with: "-")
print(replaced) // "Hello-World"
// Замена всех букв 'o' на '0'
let replaced2 = text.replacingOccurrences(of: "o", with: "0")
print(replaced2) // "Hell0 W0rld"
2. Замена с учётом регистра и локали
Метод имеет дополнительные параметры для тонкой настройки:
let text = "Hello hello HELLO"
// Без учёта регистра
let caseInsensitive = text.replacingOccurrences(
of: "hello",
with: "Hi",
options: .caseInsensitive
)
print(caseInsensitive) // "Hi Hi HELLO"
// Только первое вхождение
let firstOnly = text.replacingOccurrences(
of: "hello",
with: "Hi",
options: .caseInsensitive,
range: text.startIndex..<text.endIndex
)
// Для первого вхождения используйте range:
// (по умолчанию заменяет все)
3. Замена через NSMutableString (для Objective-C совместимости)
Если вам нужно изменить строку "на месте" (in-place):
import Foundation
var text = "Hello World"
let nsString = NSMutableString(string: text)
nsString.replaceOccurrences(
of: "o",
with: "0",
options: .literal,
range: NSRange(location: 0, length: nsString.length)
)
text = nsString as String
print(text) // "Hell0 W0rld"
4. Замена с помощью регулярных выражений
Для сложных паттернов используйте .regularExpression:
let text = "My phone: +1 (555) 123-4567"
let digitsOnly = text.replacingOccurrences(
of: "[^0-9]",
with: "",
options: .regularExpression
)
print(digitsOnly) // "15551234567"
// Замена всех гласных на '*'
let vowelsReplaced = text.replacingOccurrences(
of: "[aeiouAEIOU]",
with: "*",
options: .regularExpression
)
print(vowelsReplaced) // "My ph*n*: +1 (555) 123-4567"
5. Замена отдельных символов через map
Для точечной замены символов можно использовать map:
let text = "Swift 5.8"
let replaced = text.map { char -> Character in
if char == "." {
return ","
} else if char == " " {
return "_"
}
return char
}
print(String(replaced)) // "Swift,5_8"
6. Замена с использованием CharacterSet
Удаление или замена целых групп символов:
import Foundation
let text = "Hello 123 World! @#$"
// Удаляем все цифры
let withoutDigits = text.components(separatedBy: .decimalDigits).joined()
print(withoutDigits) // "Hello World! @#$"
// Заменяем пунктуацию на пробелы
let cleaned = text.unicodeScalars.map { scalar -> Character in
CharacterSet.punctuationCharacters.contains(scalar) ? " " : Character(scalar)
}
print(String(cleaned)) // "Hello 123 World "
Важные замечания:
- Unicode-корректность: Все методы работают корректно с эмодзи, акцентами и составными символами (например, "é" как "e" + "́")
- Производительность:
replacingOccurrencesоптимизирован и работает быстро для строк разумной длины - Неизменяемость: Большинство методов возвращают новую строку. Для изменения существующей переменной присвойте результат обратно
- Регулярные выражения: Мощный инструмент, но для простых замен избыточен — используйте обычный поиск
Для вашего примера с заменой пробелов на дефисы самым правильным решением будет:
let result = "Hello World".replacingOccurrences(of: " ", with: "-")
print(result) // Hello-World
<<Альтернативный подход: Замена через NSString API
Если вы работаете с устаревшим кодом или вам нужно больше контроля, можно использовать методы из Objective-C runtime через мост в Foundation:
import Foundation
var text = "Hello World" as NSString
let result = text.replacingOccurrences(of: " ", with: "-")
print(result) // "Hello-World"
// С указанием диапазона замены
let range = NSRange(location: 0, length: 5) // Только первые 5 символов
let partialResult = text.replacingOccurrences(
of: "l",
with: "L",
options: .literal,
range: range
)
print(partialResult) // "HeLLo World"
Замена с помощью reduce (функциональный стиль)
Для любителей функционального программирования:
let text = "Hello World"
let replacements = ["H": "J", "o": "0"]
let result = text.reduce("") { partialResult, character in
let replacement = replacements[String(character)] ?? String(character)
return partialResult + replacement
}
print(result) // "Jell0 W0rld"
Этот подход удобен, когда у вас есть словарь замен, и вы хотите применить все замены за один проход по строке. Однако для больших строк он может быть медленнее, чем replacingOccurrences, из-за конкатенации строк в цикле.
Совет: Для простых замен всегда используйте replacingOccurrences(of:with:) — это самый читаемый и производительный вариант. Регулярные выражения и функциональные подходы применяйте только когда они действительно нужны.