Regular Expressions in Swift with Examples: In Practice
Regular expressions (regex) are a powerful tool for working with text data. In Swift, the NSRegularExpression class from the Foundation framework is used for working with regular expressions. In this article, we will break down practical examples of using regular expressions in Swift for iOS and macOS applications: from simple search to complex validation and text replacement.
Basics of Working with NSRegularExpression in Swift
The NSRegularExpression class provides all the necessary methods for working with regular expressions. The basic algorithm includes three steps:
- Creating a regular expression pattern object
- Applying the pattern to a string
- Processing the results (matches, replacements)
Creating a Regular Expression
Here is how to create and apply a simple regular expression to search for the word "Swift":
import Foundation
let text = "Learning Swift and iOS development"let pattern = "Swift"
do { let regex = try NSRegularExpression(pattern: pattern) let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text)) for match in results { if let range = Range(match.range, in: text) { print("Found: \\(text[range])") } }} catch { print("Error in regular expression: \\(error.localizedDescription)")}Note the Range conversion — this is the standard way to work with positions in Swift strings. Execution result: "Found: Swift".
Practical Example 1: Searching for Email Addresses
One of the most common tasks is extracting email addresses from text. Consider an example that finds all emails in a string:
import Foundation
func findEmails(in text: String) -> [String] { let pattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,}" var emails: [String] = [] do { let regex = try NSRegularExpression(pattern: pattern) let results = regex.matches(in: text, range: NSRange(text.startIndex..., in: text)) for match in results { if let range = Range(match.range, in: text) { emails.append(String(text[range])) } } } catch { print("Error: \\(error)") } return emails}
// Usage examplelet sampleText = "Contacts: support@example.com and admin@site.org"let foundEmails = findEmails(in: sampleText)print(foundEmails) // ["support@example.com", "admin@site.org"]This pattern accounts for standard characters allowed in emails and checks for a dot in the domain part. For production, support for Cyrillic domains can be added.
Practical Example 2: Phone Number Validation
Input data validation is an important part of any application. Here is how to validate a Russian phone number in the format +7 (XXX) XXX-XX-XX:
import Foundation
func isValidPhoneNumber(_ phone: String) -> Bool { // Pattern for Russian number: +7 (XXX) XXX-XX-XX let pattern = "^\\\\+7\\\\s?\\\\(?[0-9]{3}\\\\)?\\\\s?[0-9]{3}-?[0-9]{2}-?[0-9]{2}$" do { let regex = try NSRegularExpression(pattern: pattern) let range = NSRange(location: 0, length: phone.utf16.count) return regex.firstMatch(in: phone, range: range) != nil } catch { return false }}
// Testinglet validNumbers = ["+7 (495) 123-45-67", "+74951234567", "+7 495 1234567"]let invalidNumbers = ["8 (495) 123-45-67", "+7 (495) 123-45-678", "abc"]
for number in validNumbers { print("\\(number): \\(isValidPhoneNumber(number))") // true}
for number in invalidNumbers { print("\\(number): \\(isValidPhoneNumber(number))") // false}The pattern uses an anchor