A regular expression describes a text grammar. Native Swift Regex can expose captures through a typed result, while RegexBuilder lets you compose a pattern from Swift expressions. These facilities arrived with Swift 5.7. On Apple platforms, check deployment availability; this guide targets macOS 13 or iOS 16 and later with a modern toolchain.
Review the strings lesson. A regex is useful for a compact flat pattern, but ordinary equality, prefix checks and a real structured parser remain appropriate tools. Regex does not prove business validity, authorization or the safety of an action performed after parsing.
Whole matching differs from searching
WholeMatch requires the entire input to fit the pattern. FirstMatch searches for a matching portion, and matches returns matching occurrences. An input containing a valid token surrounded by unexpected text can pass a search while failing whole-input validation. Choose the API from the task rather than add anchors without considering the operation.
The extended regex literal form begins with number-sign slash and ends with slash number-sign. It avoids depending on bare-slash literal enablement in older language modes. Parentheses capture parts of the match. A literal lets the compiler infer a structured output containing the whole match and typed capture positions.
Character classes and repetition express a grammar: [A-Z]{2} means two ASCII uppercase letters, and [0-9]{3} means three ASCII digits. That restriction is appropriate for the stock-code protocol below, not for arbitrary human names. Unicode-aware matching semantics and encoding views still matter when a pattern processes natural-language text.
RegexBuilder expresses compositional rules
Import RegexBuilder to use its domain-specific building blocks. Capture records a selected component, OneOrMore repeats a component, and TryCapture can transform a capture into a typed value while rejecting a failed conversion. Builders can make a pattern easier to maintain when captures and transformations grow beyond a short literal.
Literal regex syntax and builder syntax describe related matching behavior but are not interchangeable strings. A typed literal's capture layout comes from its syntax, while a dynamically constructed Regex from a runtime string has a different output contract and can fail during construction. Handle construction errors if users or configuration supply patterns.
Prefer a stable compiled pattern or builder value when applying the same rule repeatedly. Do not rebuild it inside every iteration without a reason. If a user supplies literal text to search, avoid interpreting that text as pattern operators; use literal matching components or an appropriate escaping strategy rather than direct unchecked interpolation.
Boundaries and performance need policy
A search for ORD followed by three digits can accidentally recognize the beginning of ORD1234 unless the grammar forbids a following digit. Test near misses, not just happy-path tokens. Word boundaries are not a universal replacement for a protocol's exact token rules, especially when underscores and Unicode letters are involved.
Patterns with ambiguous nested repetition can perform excessive work on adversarial input. Keep input sizes bounded and avoid unnecessarily complex patterns. JSON, nested documents and programming languages need parsers with the appropriate structural contract rather than a growing regex that only handles a few examples.
Native Regex uses Swift string indices and typed matches, while NSRegularExpression is a Foundation API with its own UTF-16 range handling. Do not mix their range assumptions casually. If an older deployment target requires a different API, document that alternative separately and perform the necessary string-aware range conversions.
Captured substrings can share storage with their source text. That is efficient during a local parse, but a small retained capture can keep a much larger message alive. Convert a capture to String when it becomes a long-lived independent model field, as the stock parser does. Keep temporary matches local, and avoid assuming that typed capture access also establishes the storage lifetime you intended.
Official references
The Swift 5.7 announcement records the native Regex features. The RegexBuilder proposal explains typed composition, and the Regex API documents matching. Test extra prefixes, trailing digits, empty captures, numeric boundaries and the exact supported deployment targets before adopting a pattern in production.
Swift Native Regex and Text Parsing Examples
Each example shows the code, the output it produces and what each part does.
Parse a complete stock record
The capture at position one holds the code and position two holds quantity text. Numeric parsing and range validation follow the match. No implicit trimming is applied: accepting surrounding whitespace would be a separate deliberate policy rather than an accidental consequence of searching.
struct StockRecord {
let code: String
let quantity: Int
}
func parseStock(_ text: String) -> StockRecord? {
let pattern = #/([A-Z]{2}-[0-9]{3}):([0-9]{1,3})/#
guard let match = text.wholeMatch(of: pattern),
let quantity = Int(match.2),
(1...100).contains(quantity) else { return nil }
return StockRecord(code: String(match.1), quantity: quantity)
}
if let record = parseStock("AB-042:12") {
print("\(record.code):\(record.quantity)")
}
print(parseStock("prefix AB-042:12") == nil)
print(parseStock("AB-042:999") == nil)AB-042:12
true
trueSwift Native Regex and Text Parsing in Real Projects
Worked exercise: Extract order numbers
Search a larger message for ORD plus exactly three digits, excluding a token that continues with another digit. Return numeric captures in encounter order and keep malformed or absent matches as an empty result.
func orderNumbers(in message: String) -> [Int] {
let pattern = #/ORD([0-9]{3})(?![0-9])/#
return message.matches(of: pattern).compactMap { Int($0.1) }
}
print(orderNumbers(in: "Sent ORD007 and ORD042; skip ORD1234"))
print(orderNumbers(in: "No orders today"))[7, 42]
[]Leading zeroes disappear because the result is numeric. Preserve the capture as a String when formatted identity matters. The exercise states only the trailing-digit restriction; add a preceding boundary if a form such as XORD007 must also be rejected. A parser's grammar should be written down before adding increasingly clever symbols.
Swift Native Regex and Text Parsing FAQ
Why use extended regex literals in these examples?
The extended number-sign delimiters make the regex syntax explicit and work without relying on bare-slash literal settings used by older Swift language modes. The pattern still has regex semantics and typed captures. Choose a consistent form for the project's supported toolchain, and check deployment availability for native Regex on Apple platforms. A compiler recognizing the syntax does not guarantee every target operating-system version includes the required runtime facilities.
Does a typed capture automatically validate a business quantity?
No. A capture can represent matched text, or a builder transform can produce a typed value, but domain rules still need explicit checks. An integer quantity can be syntactically valid while exceeding the accepted range. A date-shaped capture can describe an impossible calendar date. Separate text recognition, representable conversion and business validation so each rule is reviewable and a caller can receive the appropriate failure result.
Should I use RegexBuilder for every small pattern?
Not necessarily. A short readable literal can express a compact protocol more clearly than many builder lines. Builder composition becomes useful when reusable components, transformed captures or maintainable typed structure matter. Choose the form that makes the grammar easiest to verify. Avoid using either style to hide a rule nobody can explain; write sample accepted and rejected inputs first, then ensure the implementation matches those examples and their boundaries.
Can native Regex replace a JSON decoder?
No. JSON has structural rules involving nesting, escaping and value types that a dedicated decoder handles systematically. Regex is suitable for flat textual patterns and selected searches, not as a substitute for a complete structured-data contract. Use Codable or another proper parser for JSON, then validate the resulting model. A few successful regex examples do not establish correct behavior for arbitrary nested documents or adversarial escaped text.
Swift Native Regex and Text Parsing Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
A token grammar requires exactly three following digits. What near miss should a search test include?
Swift Native Regex and Text Parsing Quiz
2 questions to check what you learned.
Which operation requires the complete input to fit the stock pattern?
- firstMatch
- wholeMatch
- A search for any substring
Why does the parser check 1...100 after matching digits?
- Matching digits proves every quantity is available in stock.
- Regex automatically authorizes the caller.
- Text shape and business range are different validation rules.