🎯 Рекомендуемые коллекции
Балансированные коллекции примеров кода из различных категорий, которые вы можете исследовать
Примеры Обработки Строк macOS Swift
Примеры обработки строк macOS Swift включая разделение/объединение, регулярные выражения и замену строк
💻 Разделение/Объединение Строк swift
🟢 simple
⭐⭐
Разделить строки на компоненты и объединить массивы в строки с различными разделителями
⏱️ 25 min
🏷️ swift, macos, string processing, split join
Prerequisites:
Basic Swift knowledge
// macOS Swift String Split/Join Examples
// Using Swift standard library
import Foundation
// 1. Basic String Splitting
class StringSplitting {
static func demonstrateBasicSplit() {
print("\n--- Basic String Splitting ---")
let sentence = "Hello world from Swift"
let words = sentence.split(separator: " ")
print("Original: \(sentence)")
print("Split by space: \(words)")
// Split by character
let text = "apple,banana,cherry,date"
let fruits = text.split(separator: ",")
print("\nSplit by comma: \(fruits)")
// Split into lines
let multiline = """
Line 1
Line 2
Line 3
"""
let lines = multiline.split(separator: "\n")
print("\nSplit into lines: \(lines)")
// Using components
let components = sentence.components(separatedBy: " ")
print("\nComponents separated by space: \(components)")
}
}
// 2. Advanced Splitting
class AdvancedSplitting {
static func demonstrateAdvancedSplit() {
print("\n--- Advanced Splitting ---")
// Split by multiple separators
let text = "apple, banana; cherry| date"
let separators = CharacterSet(charactersIn: ",;|")
let parts = text.components(separatedBy: separators)
print("Split by multiple separators: \(parts)")
// Split with max splits
let data = "key1=value1,key2=value2,key3=value3"
let limited = data.components(separatedBy: ",")
print("\nSplit limited: \(limited)")
// Split by whitespace
let whitespace = " Hello world \tfrom \nSwift "
let trimmedWords = whitespace.split(separator: " ").filter { !$0.isEmpty }
print("\nSplit by whitespace: \(Array(trimmedWords))")
// Split by character set
let messyText = "Hello123World456Swift789"
let numbers = CharacterSet.decimalDigits
let nonNumbers = messyText.components(separatedBy: numbers).filter { !$0.isEmpty }
print("\nSplit removing numbers: \(nonNumbers)")
// Split keeping delimiters
func splitKeepingDelimiters(_ text: String, delimiter: String) -> [String] {
var result: [String] = []
var remaining = text
while let range = remaining.range(of: delimiter) {
let before = String(remaining[..<range.lowerBound])
result.append(before)
result.append(delimiter)
remaining = String(remaining[range.upperBound...])
}
result.append(remaining)
return result.filter { !$0.isEmpty }
}
let withDelimiters = splitKeepingDelimiters("a,b,c", delimiter: ",")
print("\nSplit keeping delimiters: \(withDelimiters)")
}
}
// 3. String Joining
class StringJoining {
static func demonstrateJoining() {
print("\n--- String Joining ---")
// Join array with separator
let words = ["Hello", "world", "from", "Swift"]
let joined = words.joined(separator: " ")
print("Words: \(words)")
print("Joined with space: \(joined)")
// Join with different separators
let fruits = ["Apple", "Banana", "Cherry"]
print("Comma-separated: \(fruits.joined(separator: ", "))")
print("Pipe-separated: \(fruits.joined(separator: " | "))")
print("Newline-separated:\n\(fruits.joined(separator: "\n"))")
// Join without separator
let letters = ["S", "w", "i", "f", "t"]
print("\nJoined without separator: \(letters.joined())")
// Join numbers
let numbers = [1, 2, 3, 4, 5]
let numberString = numbers.map { String($0) }.joined(separator: "-")
print("\nNumbers joined: \(numberString)")
// Join with prefix/suffix
let lines = ["Line 1", "Line 2", "Line 3"]
let quoted = lines.map { "\"\($0)\"" }.joined(separator: ", ")
print("\nQuoted lines: \(quoted)")
}
}
// 4. Split and Join Combinations
class SplitJoinCombinations {
static func demonstrateCombinations() {
print("\n--- Split and Join Combinations ---")
// Replace separator
let text = "apple,banana,cherry,date"
let pipeSeparated = text.split(separator: ",").joined(separator: " | ")
print("Original: \(text)")
print("With pipes: \(pipeSeparated)")
// Remove duplicates and join
let duplicates = "apple,banana,apple,cherry,banana,date"
let unique = Array(Set(duplicates.components(separatedBy: ","))).sorted().joined(separator: ",")
print("\nRemove duplicates: \(unique)")
// Filter and join
let numbers = "1,2,3,4,5,6,7,8,9,10"
let evens = numbers.split(separator: ",")
.compactMap { Int($0) }
.filter { $0 % 2 == 0 }
.map { String($0) }
.joined(separator: ",")
print("\nEven numbers: \(evens)")
// Transform and join
let names = "alice,bob,charlie"
let capitalized = names.split(separator: ",")
.map { $0.capitalized }
.joined(separator: ", ")
print("\nCapitalized: \(capitalized)")
// Word count
let paragraph = "This is a sample paragraph with several words"
let wordCount = paragraph.split(separator: " ").count
print("\nWord count: \(wordCount)")
// Parse CSV-like data
let csv = "name,age,city\nJohn,30,NYC\nJane,25,LA"
let rows = csv.split(separator: "\n")
print("\nCSV rows:")
for row in rows {
let columns = row.split(separator: ",")
print(" \(columns)")
}
}
}
// 5. String Trimming and Padding
class StringTrimmingPadding {
static func demonstrateTrimmingPadding() {
print("\n--- String Trimming and Padding ---")
// Trim whitespace
let messy = " Hello World "
print("Original: '\(messy)'")
print("Trimmed: '\(messy.trimmingCharacters(in: .whitespaces))'")
// Trim specific characters
let stars = "***Hello***"
print("\nOriginal: '\(stars)'")
print("Trimmed stars: '\(stars.trimmingCharacters(in: CharacterSet(charactersIn: "*")))'")
// Trim newlines
let withNewlines = "\nHello\n\n"
print("\nWith newlines: '\(withNewlines)'")
print("Trimmed: '\(withNewlines.trimmingCharacters(in: .newlines))'")
// Left pad
func leftPad(_ string: String, toLength length: Int, with pad: String = " ") -> String {
let padding = String(repeating: pad, count: max(0, length - string.count))
return padding + string
}
print("\nLeft pad:")
print(" '5' -> '\(leftPad("5", toLength: 3, with: "0"))'")
print(" '123' -> '\(leftPad("123", toLength: 5, with: "0"))'")
// Right pad
func rightPad(_ string: String, toLength length: Int, with pad: String = " ") -> String {
let padding = String(repeating: pad, count: max(0, length - string.count))
return string + padding
}
print("\nRight pad:")
print(" 'hi' -> '\(rightPad("hi", toLength: 5, with: "*"))'")
print(" 'hello' -> '\(rightPad("hello", toLength: 10, with: "-"))'")
// Center pad
func centerPad(_ string: String, toLength length: Int, with pad: String = " ") -> String {
let totalPad = max(0, length - string.count)
let leftPad = totalPad / 2
let rightPad = totalPad - leftPad
return String(repeating: pad, count: leftPad) + string + String(repeating: pad, count: rightPad)
}
print("\nCenter pad:")
print(" 'test' -> '\(centerPad("test", toLength: 10, with: "-"))'")
print(" 'abc' -> '\(centerPad("abc", toLength: 9, with: "*"))'")
}
}
// 6. String Parsing
class StringParsing {
static func demonstrateParsing() {
print("\n--- String Parsing ---")
// Parse key-value pairs
let query = "name=John&age=30&city=NYC"
var params: [String: String] = [:]
for pair in query.split(separator: "&") {
let keyValue = pair.split(separator: "=")
if keyValue.count == 2 {
params[String(keyValue[0])] = String(keyValue[1])
}
}
print("Query parameters: \(params)")
// Parse CSV
let csv = "John,30,New York\nJane,25,Los Angeles\nBob,35,Chicago"
print("\nCSV Parsing:")
for line in csv.split(separator: "\n") {
let fields = line.split(separator: ",")
print(" Name: \(fields[0]), Age: \(fields[1]), City: \(fields[2])")
}
// Parse file path
let path = "/Users/john/Documents/file.txt"
let components = path.split(separator: "/")
print("\nPath components: \(Array(components))")
print("Filename: \(components.last ?? "")")
print("Directory: \(components.dropLast().joined(separator: "/"))")
// Parse URL
let url = "https://example.com/path/to/page?param=value"
if let urlComponents = URLComponents(string: url) {
print("\nURL Parsing:")
print(" Scheme: \(urlComponents.scheme ?? "")")
print(" Host: \(urlComponents.host ?? "")")
print(" Path: \(urlComponents.path)")
}
// Parse words by sentence
let text = "Hello world. How are you? I'm fine!"
let sentences = text.split(separator: ".").map { $0.trimmingCharacters(in: .whitespaces) }
print("\nSentences: \(sentences)")
}
}
// 7. String Building
class StringBuilder {
static func demonstrateBuilding() {
print("\n--- String Building ---")
// Using += operator
var result1 = ""
for i in 1...5 {
result1 += "\(i) "
}
print("Using +=: '\(result1)'")
// Using append
var result2 = ""
result2.append("Hello")
result2.append(" ")
result2.append("World")
print("Using append: '\(result2)'")
// Using join
let parts = ["Hello", " ", "World", "!", " ", "From", " ", "Swift"]
let result3 = parts.joined()
print("Using join: '\(result3)'")
// Using StringInterpolation
let name = "John"
let age = 30
let result4 = "Name: \(name), Age: \(age)"
print("\nUsing interpolation: '\(result4)'")
// Large string building efficient
let largeParts = (1...1000).map { "Item\($0)" }
let startTime = Date()
let largeString = largeParts.joined(separator: ", ")
let elapsed = Date().timeIntervalSince(startTime)
print("\nBuilt string of \(largeString.count) chars in \(elapsed * 1000)ms")
}
}
// 8. String Statistics
class StringStatistics {
static func demonstrateStatistics() {
print("\n--- String Statistics ---")
let text = "Hello World from Swift"
// Character count
print("Character count: \(text.count)")
// Word count
let wordCount = text.split(separator: " ").count
print("Word count: \(wordCount)")
// Line count
let multiline = "Line 1\nLine 2\nLine 3\nLine 4"
let lineCount = multiline.split(separator: "\n").count
print("Line count: \(lineCount)")
// Unique characters
let uniqueChars = Set(text)
print("Unique characters: \(uniqueChars.count)")
// Character frequency
let chars = Array(text.lowercased().filter { !$0.isWhitespace })
var frequency: [Character: Int] = [:]
for char in chars {
frequency[char, default: 0] += 1
}
print("\nCharacter frequency:")
for (char, count) in frequency.sorted(by: { $0.value > $1.value }) {
print(" '\(char)': \(count)")
}
// Average word length
let words = text.split(separator: " ")
let avgLength = words.reduce(0) { $0 + $1.count } / words.count
print("\nAverage word length: \(avgLength)")
// Longest word
if let longest = words.max(by: { $0.count < $1.count }) {
print("Longest word: '\(longest)' (\(longest.count) chars)")
}
}
}
// 9. Path Operations
class PathOperations {
static func demonstratePaths() {
print("\n--- Path Operations ---")
let path = "/Users/john/Documents/file.txt"
// Get components
let components = path.split(separator: "/").map { String($0) }
print("Path components: \(components)")
// Get filename
let filename = (path as NSString).lastPathComponent
print("Filename: \(filename)")
// Get extension
let fileExtension = (path as NSString).pathExtension
print("Extension: \(fileExtension)")
// Get directory
let directory = (path as NSString).deletingLastPathComponent
print("Directory: \(directory)")
// Join paths
let newFilename = "data.json"
let newPath = (directory as NSString).appendingPathComponent(newFilename)
print("New path: \(newPath)")
// Normalize path
let messyPath = "/Users//john/./Documents/../john/file.txt"
let normalized = (messyPath as NSString).standardizingPath
print("\nNormalized path: \(normalized)")
}
}
// 10. Advanced String Manipulation
class AdvancedManipulation {
static func demonstrateAdvanced() {
print("\n--- Advanced String Manipulation ---")
// Reverse string
let original = "Hello Swift"
let reversed = String(original.reversed())
print("Original: \(original)")
print("Reversed: \(reversed)")
// Shuffle string
let toShuffle = "abcdef"
let shuffled = toShuffle.shuffled()
print("\nOriginal: \(toShuffle)")
print("Shuffled: \(String(shuffled))")
// Remove characters at positions
let text = "Hello World"
let indicesToRemove = [1, 5, 8]
let filtered = text.enumerated()
.filter { !indicesToRemove.contains($0.offset) }
.map { String($0.element) }
.joined()
print("\nOriginal: \(text)")
print("Removed at [1,5,8]: \(filtered)")
// Insert at position
func insert(_ string: String, at position: Int, _ toInsert: String) -> String {
let index = string.index(string.startIndex, offsetBy: position)
return string.prefix(position) + toInsert + string.suffix(from: index)
}
let base = "Hello World"
let inserted = insert(base, at: 5, " Beautiful")
print("\nOriginal: \(base)")
print("Inserted at 5: \(inserted)")
// Extract substrings
let longText = "The quick brown fox jumps over the lazy dog"
let startIndex = longText.index(longText.startIndex, offsetBy: 4)
let endIndex = longText.index(longText.startIndex, offsetBy: 9)
let substring = String(longText[startIndex..<endIndex])
print("\nSubstring [4:9]: '\(substring)'")
// First n characters
let first5 = String(longText.prefix(5))
print("First 5: '\(first5)'")
// Last n characters
let last3 = String(longText.suffix(3))
print("Last 3: '\(last3)'")
}
}
// Main demonstration
func demonstrateStringSplitJoin() {
print("=== macOS Swift String Split/Join Examples ===")
StringSplitting.demonstrateBasicSplit()
AdvancedSplitting.demonstrateAdvancedSplit()
StringJoining.demonstrateJoining()
SplitJoinCombinations.demonstrateCombinations()
StringTrimmingPadding.demonstrateTrimmingPadding()
StringParsing.demonstrateParsing()
StringBuilder.demonstrateBuilding()
StringStatistics.demonstrateStatistics()
PathOperations.demonstratePaths()
AdvancedManipulation.demonstrateAdvanced()
print("\n=== All String Split/Join Examples Completed ===")
}
// Run demonstration
demonstrateStringSplitJoin()
💻 Регулярные Выражения swift
🟡 intermediate
⭐⭐⭐⭐
Использовать регулярные выражения для сопоставления шаблонов, проверки и извлечения текста
⏱️ 35 min
🏷️ swift, macos, string processing, regex
Prerequisites:
Intermediate Swift, NSRegularExpression
// macOS Swift Regular Expression Examples
// Using NSRegularExpression and Swift Regex
import Foundation
// 1. Basic Pattern Matching
class BasicRegex {
static func demonstrateBasicMatching() {
print("\n--- Basic Pattern Matching ---")
let text = "Hello World! Swift is awesome. Welcome to Swift programming."
// Simple match
if let range = text.range(of: "Swift", options: .regularExpression) {
print("Found 'Swift' at: \(range)")
}
// Match digits
let numberPattern = "\d+"
if let _ = text.range(of: numberPattern, options: .regularExpression) {
print("Found numbers in text")
}
// Match word
let wordPattern = "\b\w{5}\b" // 5-letter words
if let range = text.range(of: wordPattern, options: .regularExpression) {
let word = String(text[range])
print("Found 5-letter word: \(word)")
}
}
}
// 2. NSRegularExpression Usage
class NSRegularExpressionExamples {
static func demonstrateNSRegularExpression() {
print("\n--- NSRegularExpression ---")
let text = "Emails: [email protected], [email protected], [email protected]"
do {
// Email pattern
let emailPattern = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
let regex = try NSRegularExpression(pattern: emailPattern)
let range = NSRange(text.startIndex..., in: text)
let matches = regex.matches(in: text, range: range)
print("Found \(matches.count) emails:")
for match in matches {
if let range = Range(match.range, in: text) {
print(" \(String(text[range]))")
}
}
} catch {
print("Regex error: \(error)")
}
}
}
// 3. Text Validation
class RegexValidation {
static func demonstrateValidation() {
print("\n--- Regex Validation ---")
// Email validation
func isValidEmail(_ email: String) -> Bool {
let pattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
return predicate.evaluate(with: email)
}
print("Email validation:")
print(" [email protected]: \(isValidEmail("[email protected]"))")
print(" invalid.email: \(isValidEmail("invalid.email"))")
// Phone number validation
func isValidPhone(_ phone: String) -> Bool {
let pattern = "^\\d{3}-\\d{3}-\\d{4}$"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
return predicate.evaluate(with: phone)
}
print("\nPhone validation (XXX-XXX-XXXX):")
print(" 123-456-7890: \(isValidPhone("123-456-7890"))")
print(" 12-345-67890: \(isValidPhone("12-345-67890"))")
// URL validation
func isValidURL(_ url: String) -> Bool {
let pattern = "^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\/\\w \\.-]*)*\\/?$"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
return predicate.evaluate(with: url)
}
print("\nURL validation:")
print(" https://example.com: \(isValidURL("https://example.com"))")
print(" not-a-url: \(isValidURL("not-a-url"))")
// Password strength
func isStrongPassword(_ password: String) -> Bool {
// At least 8 chars, 1 uppercase, 1 lowercase, 1 number
let pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}$"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
return predicate.evaluate(with: password)
}
print("\nPassword validation:")
print(" Pass123: \(isStrongPassword("Pass123"))")
print(" weak: \(isStrongPassword("weak"))")
print(" StrongPass123: \(isStrongPassword("StrongPass123"))")
}
}
// 4. Text Extraction
class RegexExtraction {
static func demonstrateExtraction() {
print("\n--- Text Extraction ---")
let text = """
The prices are: $19.99, $29.99, and $5.50.
Contact us at [email protected] or [email protected].
Phone numbers: 123-456-7890, 987-654-3210
"""
// Extract prices
extractAndPrint(text, pattern: "\\$\\d+\\.\\d{2}", label: "Prices")
// Extract emails
extractAndPrint(text, pattern: "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}", label: "Emails")
// Extract phone numbers
extractAndPrint(text, pattern: "\\d{3}-\\d{3}-\\d{4}", label: "Phone numbers")
// Extract URLs
let html = "Visit https://example.com and http://test.org for info"
extractAndPrint(html, pattern: "https?:\\/\\/[^\\s]+", label: "URLs")
// Extract dates
let dates = "Events: 2024-01-15, 2024-02-20, 2024-03-25"
extractAndPrint(dates, pattern: "\\d{4}-\\d{2}-\\d{2}", label: "Dates")
// Extract hashtags
let social = "Check out #Swift and #Programming and #iOSDev"
extractAndPrint(social, pattern: "#\\w+", label: "Hashtags")
// Extract mentions
let mentions = "Hello @john and @jane, welcome @all"
extractAndPrint(mentions, pattern: "@\\w+", label: "Mentions")
}
private static func extractAndPrint(_ text: String, pattern: String, label: String) {
do {
let regex = try NSRegularExpression(pattern: pattern)
let range = NSRange(text.startIndex..., in: text)
let matches = regex.matches(in: text, range: range)
print("\n\(label):")
for match in matches {
if let range = Range(match.range, in: text) {
print(" \(String(text[range]))")
}
}
} catch {
print("Error extracting \(label): \(error)")
}
}
}
// 5. Text Replacement
class RegexReplacement {
static func demonstrateReplacement() {
print("\n--- Regex Replacement ---")
// Mask phone numbers
func maskPhoneNumbers(_ text: String) -> String {
let pattern = "(\\d{3})-(\\d{3})-(\\d{4})"
return text.replacingOccurrences(
of: pattern,
with: "$1-XXX-$3",
options: .regularExpression
)
}
let phones = "Call 123-456-7890 or 987-654-3210"
print("Original: \(phones)")
print("Masked: \(maskPhoneNumbers(phones))")
// Remove special characters
func removeSpecialChars(_ text: String) -> String {
let pattern = "[^a-zA-Z0-9\\s]"
return text.replacingOccurrences(
of: pattern,
with: "",
options: .regularExpression
)
}
let messy = "Hello! @World #123 $Test"
print("\nOriginal: \(messy)")
print("Cleaned: \(removeSpecialChars(messy))")
// Normalize whitespace
func normalizeWhitespace(_ text: String) -> String {
let pattern = "\\s+"
return text.replacingOccurrences(
of: pattern,
with: " ",
options: .regularExpression
).trimmingCharacters(in: .whitespaces)
}
let messyText = " Hello world from Swift "
print("\nOriginal: '\(messyText)'")
print("Normalized: '\(normalizeWhitespace(messyText))'")
// Format phone numbers
func formatPhone(_ text: String) -> String {
let pattern = "(\\d{3})(\\d{3})(\\d{4})"
return text.replacingOccurrences(
of: pattern,
with: "($1) $2-$3",
options: .regularExpression
)
}
let plainPhone = "1234567890"
print("\nPlain: \(plainPhone)")
print("Formatted: \(formatPhone(plainPhone))")
// Remove HTML tags
func stripHTML(_ html: String) -> String {
let pattern = "<[^>]+>"
return html.replacingOccurrences(
of: pattern,
with: "",
options: .regularExpression
)
}
let html = "<p>Hello <b>World</b>!</p>"
print("\nHTML: \(html)")
print("Stripped: \(stripHTML(html))")
}
}
// 6. Text Searching
class RegexSearch {
static func demonstrateSearch() {
print("\n--- Regex Search ---")
let text = """
Swift is a powerful programming language.
Swift was developed by Apple for iOS development.
Many developers love Swift because it's modern and safe.
"""
// Count occurrences
func countOccurrences(_ text: String, pattern: String) -> Int {
do {
let regex = try NSRegularExpression(pattern: pattern)
let range = NSRange(text.startIndex..., in: text)
return regex.numberOfMatches(in: text, range: range)
} catch {
return 0
}
}
let swiftCount = countOccurrences(text, pattern: "Swift")
print("Count of 'Swift': \(swiftCount)")
// Find all words
func findAllWords(_ text: String) -> [String] {
do {
let pattern = "\\b\\w+\\b"
let regex = try NSRegularExpression(pattern: pattern)
let range = NSRange(text.startIndex..., in: text)
let matches = regex.matches(in: text, range: range)
return matches.compactMap { match -> String? in
if let range = Range(match.range, in: text) {
return String(text[range])
}
return nil
}
} catch {
return []
}
}
let words = findAllWords(text)
print("\nAll words (\(words.count)): \(words)")
// Find words starting with capital letter
func findCapitalizedWords(_ text: String) -> [String] {
do {
let pattern = "\\b[A-Z]\\w*\\b"
let regex = try NSRegularExpression(pattern: pattern)
let range = NSRange(text.startIndex..., in: text)
let matches = regex.matches(in: text, range: range)
return matches.compactMap { match -> String? in
if let range = Range(match.range, in: text) {
return String(text[range])
}
return nil
}
} catch {
return []
}
}
let capitalized = findCapitalizedWords(text)
print("\nCapitalized words: \(capitalized)")
// Search with case insensitive
func searchCaseInsensitive(_ text: String, searchTerm: String) -> [NSRange] {
do {
let pattern = NSRegularExpression.escapedPattern(for: searchTerm)
let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let range = NSRange(text.startIndex..., in: text)
return regex.matches(in: text, range: range).map { $0.range }
} catch {
return []
}
}
let searchResults = searchCaseInsensitive(text, searchTerm: "swift")
print("\nFound 'swift' (case insensitive) at \(searchResults.count) locations")
}
}
// 7. Advanced Patterns
class AdvancedPatterns {
static func demonstrateAdvanced() {
print("\n--- Advanced Patterns ---")
// IPv4 address validation
func isValidIP(_ ip: String) -> Bool {
let pattern = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
return predicate.evaluate(with: ip)
}
print("IP validation:")
print(" 192.168.1.1: \(isValidIP("192.168.1.1"))")
print(" 256.1.1.1: \(isValidIP("256.1.1.1"))")
// Credit card pattern (simplified)
func formatCreditCard(_ number: String) -> String {
let pattern = "(\\d{4})(\\d{4})(\\d{4})(\\d{4})"
return number.replacingOccurrences(
of: pattern,
with: "$1 $2 $3 $4",
options: .regularExpression
)
}
let card = "1234567890123456"
print("\nCredit card: \(formatCreditCard(card))")
// Hex color code validation
func isValidHexColor(_ color: String) -> Bool {
let pattern = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
return predicate.evaluate(with: color)
}
print("\nHex color validation:")
print(" #FF0000: \(isValidHexColor("#FF0000"))")
print(" #FFF: \(isValidHexColor("#FFF"))")
print(" #GGG: \(isValidHexColor("#GGG"))")
// Social Security Number (US)
func isValidSSN(_ ssn: String) -> Bool {
let pattern = "^(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}$"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
return predicate.evaluate(with: ssn)
}
print("\nSSN validation:")
print(" 123-45-6789: \(isValidSSN("123-45-6789"))")
print(" 000-00-0000: \(isValidSSN("000-00-0000"))")
// Date format validation (YYYY-MM-DD)
func isValidDate(_ date: String) -> Bool {
let pattern = "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
return predicate.evaluate(with: date)
}
print("\nDate validation:")
print(" 2024-01-15: \(isValidDate("2024-01-15"))")
print(" 2024-13-01: \(isValidDate("2024-13-01"))")
}
}
// 8. Regex Options and Flags
class RegexOptions {
static func demonstrateOptions() {
print("\n--- Regex Options ---")
let text = "Hello WORLD. This is a TEST. hello world."
// Case insensitive
func findCaseInsensitive(_ text: String, pattern: String) -> Int {
do {
let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let range = NSRange(text.startIndex..., in: text)
return regex.numberOfMatches(in: text, range: range)
} catch {
return 0
}
}
print("Case insensitive 'hello': \(findCaseInsensitive(text, pattern: "hello"))")
// Anchors match line
let multiline = """
Line 1 start
Line 2 start
Line 3 start
"""
func countLineStarts(_ text: String) -> Int {
do {
let regex = try NSRegularExpression(pattern: "^Line", options: .anchorsMatchLines)
let range = NSRange(text.startIndex..., in: text)
return regex.numberOfMatches(in: text, range: range)
} catch {
return 0
}
}
print("\nLine starts with 'Line': \(countLineStarts(multiline))")
}
}
// 9. Performance Tips
class RegexPerformance {
static func demonstratePerformance() {
print("\n--- Regex Performance Tips ---")
// Cache compiled regex
class RegexCache {
static var cache: [String: NSRegularExpression] = [:]
static func get(_ pattern: String) -> NSRegularExpression? {
if let cached = cache[pattern] {
return cached
}
do {
let regex = try NSRegularExpression(pattern: pattern)
cache[pattern] = regex
return regex
} catch {
return nil
}
}
}
// Use cached regex
func findEmails(_ text: String) -> [String] {
let pattern = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"
guard let regex = RegexCache.get(pattern) else {
return []
}
let range = NSRange(text.startIndex..., in: text)
let matches = regex.matches(in: text, range: range)
return matches.compactMap { match -> String? in
if let range = Range(match.range, in: text) {
return String(text[range])
}
return nil
}
}
let text = "Contact: [email protected] or [email protected]"
let emails = findEmails(text)
print("Found emails: \(emails)")
// Pre-compile for repeated use
let emailPattern = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"
do {
let compiledRegex = try NSRegularExpression(pattern: emailPattern)
// Use compiled regex multiple times
for _ in 0..<10 {
let range = NSRange(text.startIndex..., in: text)
_ = compiledRegex.matches(in: text, range: range)
}
print("Compiled regex used 10 times")
} catch {
print("Regex error: \(error)")
}
}
}
// 10. Real-World Examples
class RealWorldRegex {
static func demonstrateRealWorld() {
print("\n--- Real-World Regex Examples ---")
// Parse log file format
let log = "[2024-01-15 10:30:45] ERROR: File not found at /path/to/file.txt"
func parseLog(_ log: String) -> [String: String] {
var result: [String: String] = [:]
// Extract timestamp
if let timestampRange = log.range(of: "\\\[^\\]+\\]", options: .regularExpression) {
result["timestamp"] = String(log[timestampRange]).trimmingCharacters(in: CharacterSet(charactersIn: "[]"))
}
// Extract log level
if let levelRange = log.range(of: "(ERROR|WARN|INFO|DEBUG)", options: .regularExpression) {
result["level"] = String(log[levelRange])
}
// Extract message
if let messageRange = log.range(of: ": .*", options: .regularExpression) {
result["message"] = String(log[messageRange]).dropFirst(2).description
}
return result
}
let parsed = parseLog(log)
print("Parsed log:")
parsed.forEach { key, value in
print(" \(key): \(value)")
}
// Extract markdown links
let markdown = "Check [Swift](https://swift.org) and [Apple](https://apple.com)"
func extractMarkdownLinks(_ text: String) -> [(text: String, url: String)] {
let pattern = "\\\[([^\\]]+)\\]\\(([^\\)]+)\\)"
do {
let regex = try NSRegularExpression(pattern: pattern)
let range = NSRange(text.startIndex..., in: text)
let matches = regex.matches(in: text, range: range)
return matches.compactMap { match -> (String, String)? in
guard match.numberOfRanges == 3,
let textRange = Range(match.range(at: 1), in: text),
let urlRange = Range(match.range(at: 2), in: text) else {
return nil
}
return (String(text[textRange]), String(text[urlRange]))
}
} catch {
return []
}
}
let links = extractMarkdownLinks(markdown)
print("\nMarkdown links:")
for link in links {
print(" [\(link.text)](\(link.url))")
}
}
}
// Main demonstration
func demonstrateRegex() {
print("=== macOS Swift Regular Expression Examples ===")
BasicRegex.demonstrateBasicMatching()
NSRegularExpressionExamples.demonstrateNSRegularExpression()
RegexValidation.demonstrateValidation()
RegexExtraction.demonstrateExtraction()
RegexReplacement.demonstrateReplacement()
RegexSearch.demonstrateSearch()
AdvancedPatterns.demonstrateAdvanced()
RegexOptions.demonstrateOptions()
RegexPerformance.demonstratePerformance()
RealWorldRegex.demonstrateRealWorld()
print("\n=== All Regular Expression Examples Completed ===")
}
// Run demonstration
demonstrateRegex()
💻 Замена Строк swift
🟡 intermediate
⭐⭐⭐
Заменять подстроки используя простую замену, замену с regex и пользовательскую логику
⏱️ 30 min
🏷️ swift, macos, string processing, replacement
Prerequisites:
Intermediate Swift, String manipulation
// macOS Swift String Replacement Examples
// Using Swift standard library
import Foundation
// 1. Basic String Replacement
class BasicReplacement {
static func demonstrateBasicReplacement() {
print("\n--- Basic String Replacement ---")
let text = "Hello World! Welcome to World of programming."
// Simple replacement
let replaced = text.replacingOccurrences(of: "World", with: "Swift")
print("Original: \(text)")
print("Replaced: \(replaced)")
// Case sensitive replacement
let caseSensitive = text.replacingOccurrences(of: "world", with: "Universe")
print("\nCase sensitive: \(caseSensitive)")
// Case insensitive replacement
let caseInsensitive = text.replacingOccurrences(
of: "world",
with: "Universe",
options: .caseInsensitive
)
print("Case insensitive: \(caseInsensitive)")
// Replace first occurrence only
func replaceFirst(_ text: String, of: String, with: String) -> String {
guard let range = text.range(of: of) else { return text }
return text.replacingCharacters(in: range, with: with)
}
let firstOnly = replaceFirst(text, of: "World", with: "Swift")
print("\nReplace first only: \(firstOnly)")
}
}
// 2. Multiple Replacements
class MultipleReplacements {
static func demonstrateMultipleReplacements() {
print("\n--- Multiple Replacements ---")
let text = "The quick brown fox jumps over the lazy dog."
// Replace multiple words
var result = text
let replacements = [
("quick", "slow"),
("brown", "white"),
("fox", "rabbit")
]
for (old, new) in replacements {
result = result.replacingOccurrences(of: old, with: new)
}
print("Original: \(text)")
print("After multiple replacements: \(result)")
// Replace all vowels
let vowels = "aeiouAEIOU"
let noVowels = text.unicodeScalars
.map { vowels.contains(String($0)) ? "*" : String($0) }
.joined()
print("\nRemove vowels: \(noVowels)")
// Chain replacements
func chainReplace(_ text: String, _ replacements: [(String, String)]) -> String {
return replacements.reduce(text) { result, replacement in
result.replacingOccurrences(of: replacement.0, with: replacement.1)
}
}
let chained = chainReplace(text, [
("The", "A"),
("quick", "fast"),
("lazy", "sleeping")
])
print("\nChained replacements: \(chained)")
}
}
// 3. Regex Replacement
class RegexReplacement {
static func demonstrateRegexReplacement() {
print("\n--- Regex Replacement ---")
// Mask email addresses
func maskEmails(_ text: String) -> String {
return text.replacingOccurrences(
of: "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}",
with: "***@***.***",
options: .regularExpression
)
}
let emails = "Contact [email protected] or [email protected] for help"
print("Original: \(emails)")
print("Masked: \(maskEmails(emails))")
// Remove all numbers
func removeNumbers(_ text: String) -> String {
return text.replacingOccurrences(
of: "\\d+",
with: "",
options: .regularExpression
)
}
let withNumbers = "Order #12345 for $67.89 with 10 items"
print("\nOriginal: \(withNumbers)")
print("No numbers: \(removeNumbers(withNumbers))")
// Format currency
func formatCurrency(_ text: String) -> String {
return text.replacingOccurrences(
of: "\\$?(\\d+\\.\\d{2})",
with: "$$$1",
options: .regularExpression
)
}
let prices = "Items cost 19.99, 29.99, and 5.50 dollars"
print("\nOriginal: \(prices)")
print("Formatted: \(formatCurrency(prices))")
// Normalize phone numbers
func normalizePhone(_ text: String) -> String {
// Remove all non-digits
let digits = text.replacingOccurrences(
of: "\\D",
with: "",
options: .regularExpression
)
// Format as (XXX) XXX-XXXX
if digits.count == 10 {
let index1 = digits.index(digits.startIndex, offsetBy: 3)
let index2 = digits.index(digits.startIndex, offsetBy: 6)
return "(\(digits[..<index1])) \(digits[index1..<index2])-\(digits[index2...])"
}
return digits
}
let phones = "Call 123-456-7890 or (987) 654 3210"
print("\nOriginal: \(phones)")
print("Normalized: \(normalizePhone(phones))")
}
}
// 4. Conditional Replacement
class ConditionalReplacement {
static func demonstrateConditional() {
print("\n--- Conditional Replacement ---")
// Replace based on condition
func replaceIfCondition(_ text: String, predicate: (Character) -> Bool, with: String) -> String {
return text.map { char in
predicate(char) ? with : String(char)
}.joined()
}
let text = "Hello123World456"
let lettersOnly = replaceIfCondition(text) { $0.isNumber }
.with: ""
print("Original: \(text)")
print("Letters only: \(lettersOnly)")
let numbersAsHash = replaceIfCondition(text) { $0.isNumber }
.with: "#"
print("Numbers as #: \(numbersAsHash)")
// Replace words longer than threshold
func replaceLongWords(_ text: String, threshold: Int) -> String {
return text.components(separatedBy: " ").map { word in
word.count > threshold ? String(repeating: "*", count: word.count) : word
}.joined(separator: " ")
}
let sentence = "The quick brown fox jumps over the lazy dog"
print("\nOriginal: \(sentence)")
print("Words > 4 chars masked: \(replaceLongWords(sentence, threshold: 4))")
// Replace based on context
func replaceInContext(_ text: String, target: String, replacement: String, context: String) -> String {
var result = text
let contextWithTarget = context + " " + target
result = result.replacingOccurrences(
of: contextWithTarget,
with: context + " " + replacement
)
return result
}
let story = "The red apple. The red ball. The blue car."
let contextual = replaceInContext(story, target: "red", replacement: "green", context: "The")
print("\nContextual replacement: \(contextual)")
}
}
// 5. Batch Replacement with Dictionary
class DictionaryReplacement {
static func demonstrateDictionaryReplacement() {
print("\n--- Dictionary Replacement ---")
let abbreviations = [
"API": "Application Programming Interface",
"UI": "User Interface",
"UX": "User Experience",
"HTTP": "HyperText Transfer Protocol"
]
let text = "The API uses HTTP to send data to the UI and affects the UX."
// Replace using dictionary
func expandAbbreviations(_ text: String, _ abbreviations: [String: String]) -> String {
var result = text
for (abbr, expansion) in abbreviations {
result = result.replacingOccurrences(
of: "\\\(abbr)\\b",
with: expansion,
options: .regularExpression
)
}
return result
}
print("Original: \(text)")
print("Expanded: \(expandAbbreviations(text, abbreviations))")
// Smart replacement (only whole words)
func smartReplace(_ text: String, _ replacements: [String: String]) -> String {
var result = text
for (from, to) in replacements {
let pattern = "\\\(from)\\b"
result = result.replacingOccurrences(
of: pattern,
with: to,
options: .regularExpression
)
}
return result
}
let smartText = "cat catalog concatenate"
let smartReplacements = ["cat": "dog"]
print("\nOriginal: \(smartText)")
print("Smart replacement: \(smartReplace(smartText, smartReplacements))")
}
}
// 6. Template Replacement
class TemplateReplacement {
static func demonstrateTemplateReplacement() {
print("\n--- Template Replacement ---")
// Simple template engine
func renderTemplate(_ template: String, _ variables: [String: Any]) -> String {
var result = template
for (key, value) in variables {
let placeholder = "{{\(key)}}"
result = result.replacingOccurrences(of: placeholder, with: "\(value)")
}
return result
}
let template = """
Dear {{name}},
Your order {{orderId}} has been shipped.
Expected delivery: {{deliveryDate}}
Thank you for shopping with {{company}}!
"""
let data: [String: Any] = [
"name": "John Doe",
"orderId": "12345",
"deliveryDate": "2024-01-20",
"company": "Swift Store"
]
print("Template:")
print(template)
print("\nRendered:")
print(renderTemplate(template, data))
// Nested template
func renderNestedTemplate(_ template: String, _ data: [String: Any]) -> String {
var result = template
// Handle {{key.nestedKey}}
func replaceNested(_ match: String) -> String {
let keyPath = match.dropFirst(2).dropLast(2) // Remove {{ }}
let parts = keyPath.split(separator: ".")
var current: Any? = data
for part in parts {
if let dict = current as? [String: Any] {
current = dict[String(part)]
}
}
return "\(current ?? "")"
}
let pattern = "\\\{\{[^}]+\\\\}\\}"
let regex = try? NSRegularExpression(pattern: pattern)
let range = NSRange(template.startIndex..., in: template)
if let regex = regex {
let matches = regex.matches(in: template, range: range).reversed()
for match in matches {
if let matchRange = Range(match.range, in: result) {
let matchString = String(result[matchRange])
result = result.replacingCharacters(in: matchRange, with: replaceNested(matchString))
}
}
}
return result
}
let nestedTemplate = "User: {{user.name}}, Email: {{user.email}}"
let nestedData: [String: Any] = [
"user": [
"name": "Alice",
"email": "[email protected]"
]
]
print("\nNested template: \(nestedTemplate)")
print("Rendered: \(renderNestedTemplate(nestedTemplate, nestedData))")
}
}
// 7. Range-based Replacement
class RangeReplacement {
static void demonstrateRangeReplacement() {
print("\n--- Range-based Replacement ---")
let text = "Hello World! This is a test string."
// Replace by index range
let startIndex = text.index(text.startIndex, offsetBy: 6)
let endIndex = text.index(text.startIndex, offsetBy: 11)
let range = startIndex..<endIndex
let rangeReplaced = text.replacingCharacters(in: range, with: "Swift")
print("Original: \(text)")
print("Replaced chars 6-11: \(rangeReplaced)")
// Replace first N characters
func replaceFirstN(_ text: String, n: Int, with: String) -> String {
let endIndex = text.index(text.startIndex, offsetBy: min(n, text.count))
return text.replacingCharacters(in: text.startIndex..<endIndex, with: with)
}
let first5Replaced = replaceFirstN(text, n: 5, with: "Hi")
print("\nReplace first 5: \(first5Replaced)")
// Replace last N characters
func replaceLastN(_ text: String, n: Int, with: String) -> String {
let startIndex = text.index(text.endIndex, offsetBy: -min(n, text.count))
return text.replacingCharacters(in: startIndex..<text.endIndex, with: with)
}
let last7Replaced = replaceLastN(text, n: 7, with: "done.")
print("\nReplace last 7: \(last7Replaced)")
// Replace between two strings
func replaceBetween(_ text: String, from: String, to: String, with: String) -> String {
guard let fromRange = text.range(of: from),
let toRange = text.range(of: to, range: fromRange.upperBound..<text.endIndex) else {
return text
}
let replaceRange = fromRange.upperBound..<toRange.lowerBound
return text.replacingCharacters(in: replaceRange, with: with)
}
let markers = "START [content to replace] END"
let betweenReplaced = replaceBetween(markers, from: "START", to: "END", with: "NEW CONTENT")
print("\nReplace between markers: \(betweenReplaced)")
}
}
// 8. Transliteration
class Transliteration {
static void demonstrateTransliteration() {
print("\n--- Transliteration ---")
// Character mapping
func transliterate(_ text: String, _ mapping: [Character: String]) -> String {
return text.map { char in
mapping[char, default: String(char)]
}.joined()
}
let leetSpeak: [Character: String] = [
"a": "4",
"e": "3",
"i": "1",
"o": "0",
"s": "5",
"t": "7"
]
let normal = "Hello elite hackers"
let leet = transliterate(normal.lowercased(), leetSpeak)
print("Normal: \(normal)")
print("Leet speak: \(leet)")
// ROT13
func rot13(_ text: String) -> String {
return text.map { char in
if char.isLetter {
let base = char.isUppercase ? Character("A") : Character("a")
let offset = (char.asciiValue! - base.asciiValue! + 13) % 26
return Character(UnicodeScalar(base.asciiValue! + offset))
}
return char
}.joined()
}
let secret = "Hello World"
let encoded = rot13(secret)
print("\nOriginal: \(secret)")
print("ROT13: \(encoded)")
print("Decoded: \(rot13(encoded))")
// To lowercase/uppercase
func toggleCase(_ text: String) -> String {
return text.map { char in
char.isUppercase ? char.lowercased() : char.uppercased()
}.joined()
}
let mixed = "HeLLo WoRLd"
print("\nOriginal: \(mixed)")
print("Toggled case: \(toggleCase(mixed))")
}
}
// 9. Text Cleanup
class TextCleanup {
static void demonstrateCleanup() {
print("\n--- Text Cleanup ---")
// Remove extra whitespace
func cleanWhitespace(_ text: String) -> String {
let collapsed = text.replacingOccurrences(
of: "\\s+",
with: " ",
options: .regularExpression
)
return collapsed.trimmingCharacters(in: .whitespacesAndNewlines)
}
let messy = " Hello world from Swift \n\n "
print("Original: '\(messy)'")
print("Cleaned: '\(cleanWhitespace(messy))'")
// Remove special characters
func cleanSpecialChars(_ text: String, keep: String = "") -> String {
var allowed = CharacterSet.alphanumerics
allowed.insert(charactersIn: " \n\t" + keep)
return text.components(separatedBy: allowed.inverted)
.joined()
}
let special = "Hello! @World #123 $Test"
print("\nOriginal: \(special)")
print("Keep alphanumeric: \(cleanSpecialChars(special))")
print("Keep alphanumeric + #: \(cleanSpecialChars(special, keep: "#"))")
// Normalize line endings
func normalizeLineEndings(_ text: String) -> String {
return text.replacingOccurrences(
of: "\\r\\n|\\r",
with: "\n",
options: .regularExpression
)
}
let mixedEndings = "Line1\r\nLine2\rLine3\nLine4"
print("\nMixed line endings normalized:")
print(normalizeLineEndings(mixedEndings))
// Remove duplicate lines
func removeDuplicateLines(_ text: String) -> String {
let lines = text.components(separatedBy: "\n")
let unique = Array(Set(lines))
return unique.joined(separator: "\n")
}
let dupLines = """
Line 1
Line 2
Line 1
Line 3
Line 2
"""
print("\nOriginal with duplicates:")
print(removeDuplicateLines(dupLines))
}
}
// 10. Smart Replacement
class SmartReplacement {
static void demonstrateSmartReplacement() {
print("\n--- Smart Replacement ---")
// Avoid replacing already replaced
func replaceWithoutDuplicates(_ text: String, target: String, replacement: String) -> String {
var result = text
var replacedRanges: [Range<String.Index>] = []
while let range = result.range(of: target) {
// Check if this range overlaps with already replaced
let overlaps = replacedRanges.contains { replacedRange in
!(range.upperBound < replacedRange.lowerBound || range.lowerBound > replacedRange.upperBound)
}
if !overlaps {
result = result.replacingCharacters(in: range, with: replacement)
let newRange = result.range(of: replacement, range: range)
if let newRange = newRange {
replacedRanges.append(newRange)
}
}
// Continue search after this range
let searchStart = result.index(after: range.upperBound)
guard searchStart < result.endIndex else { break }
}
return result
}
let overlapText = "test testest"
print("Original: \(overlapText)")
print("Smart replace 'test' with 'X': \(replaceWithoutDuplicates(overlapText, target: "test", replacement: "X"))")
// Preserve case
func replacePreservingCase(_ text: String, target: String, replacement: String) -> String {
let pattern = NSRegularExpression.escapedPattern(for: target)
do {
let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let range = NSRange(text.startIndex..., in: text)
let result = regex.stringByReplacingMatches(
in: text,
options: [],
range: range,
withTemplate: replacement
)
// Fix case (simplified - real implementation would need more sophisticated logic)
return result
} catch {
return text
}
}
let caseText = "The TEST and Test are in test"
print("\nOriginal: \(caseText)")
print("Replace 'test' with 'example': \(replacePreservingCase(caseText, target: "test", replacement: "example"))")
}
}
// Main demonstration
func demonstrateStringReplacement() {
print("=== macOS Swift String Replacement Examples ===")
BasicReplacement.demonstrateBasicReplacement()
MultipleReplacements.demonstrateMultipleReplacements()
RegexReplacement.demonstrateRegexReplacement()
ConditionalReplacement.demonstrateConditional()
DictionaryReplacement.demonstrateDictionaryReplacement()
TemplateReplacement.demonstrateTemplateReplacement()
RangeReplacement.demonstrateRangeReplacement()
Transliteration.demonstrateTransliteration()
TextCleanup.demonstrateCleanup()
SmartReplacement.demonstrateSmartReplacement()
print("\n=== All String Replacement Examples Completed ===")
}
// Run demonstration
demonstrateStringReplacement()