CocoaPods trunk is moving to be read-only. Read more on the blog, there are 19 months to go.
TestsTested | ✗ |
LangLanguage | SwiftSwift |
License | MIT |
ReleasedLast Release | Sep 2017 |
SwiftSwift Version | 4.0 |
SPMSupports SPM | ✓ |
Maintained by Rock Young.
Regular expression library in Swift, wrapping NSRegularExpression. Don’t hesitate to try out on playground.
dependencies: [
.Package(url: "https://github.com/LittleRockInGitHub/LLRegex.git", majorVersion: 1)
]
let numbers = Regex("(\\d)(\\d+)(\\d)")
let insensitive = Regex("LLRegex", options: [.caseInsensitive])
let runtimeError = Regex("") // Runtime error would be raised
let invalid = try? Regex(pattern: "") // nil returned
Method matches(in:options:range:)
returns a sequence producing matches lazily, which is the only one for searching. All other variants were dropped thanks to the power of Sequence.
let s = "123-45-6789-0-123-45-6789-01234"
let subrange = s.characters.dropFirst(3).startIndex..<s.endIndex
for match in numbers.matches(in: s) {
// enumerating
match.matched
}
if let first = numbers.matches(in: s).first {
// first match
first.matched
}
let allMatches: [Match] = numbers.matches(in: s).all // all matches
let subrangeMatches = numbers.matches(in: s, options: [.withTransparentBounds], range: subrange)
for case let match in subrangeMatches.dropFirst(1) where match.matched != "6789" {
match.matched
}
Range<String.Index>
, the match is ignored . Try searching “\r” in “\r\n”.if let first = numbers.matches(in: s).first {
first.matched
first.range
first.groups.count
first.groups[1].matched
first.groups[1].range
let replacement = first.replacement(withTemplate: "$3$2$1") // Replacement with template
}
Named capture group feature is enabled when .namedCaptureGroups
is set.
let named = Regex("(?<year>\\d+)-(?<month>\\d+)-(?<day>\\d+)", options: .namedCaptureGroups)
let s = "Today is 2017-06-23."
for m in named.matches(in: s) {
m.groups["year"]?.matched
}
named.replacingAllMatches(in: s, replacement: .replaceWithTemplate("${month}/${day}/${year}")) // Today is 06/23/2017.
numbers.replacingFirstMatch(in: s, replacement: .remove)
numbers.replacingAllMatches(in: s, range: subrange, replacement: .replaceWithTemplate("$3$2$1"))
Flexible Find & Replace is offered by replacingMatches(in:options:range:replacing:)
.
numbers.replacingMatches(in: s) { (idx, match) -> Match.Replacing in
switch idx {
case 0:
return .keep // Keeps unchanged
case 1:
return .remove // Removes the matched string
case 2:
return .replaceWithTemplate("($1-$3)") // Replaces with template
case 3:
return .replaceWithString(String(match.matched.characters.reversed())) // Replaces with string
default:
return .stop // Stops replacing
}
}
"123".isMatching("\\d+")
"llregex".isMatching(insensitive) // Regex is accepted
"123-456".isMatching("\\d+") // isMatching(_:) checks whether matches entirely
"123".replacingAll("1", with: "$0")
"123-321".replacingAll(pattern: "(\\d)(\\d)", withTemplate: "$2$1")
s.replacingFirst(pattern: numbers, in: subrange, withTemplate: "!")
s.split(seperator: "\\d")
s.split(seperator: numbers, maxSplits: 2, omittingEmptyString: false)