mirror of
https://github.com/kean/Pulse.git
synced 2026-05-30 21:07:33 +00:00
56 lines
1.8 KiB
Swift
56 lines
1.8 KiB
Swift
// The MIT License (MIT)
|
|
//
|
|
// Copyright (c) 2020-2024 Alexander Grebenyuk (github.com/kean).
|
|
|
|
import Foundation
|
|
|
|
final class Regex {
|
|
private let regex: NSRegularExpression
|
|
|
|
struct Options: OptionSet {
|
|
let rawValue: Int
|
|
|
|
static let caseInsensitive = Options(rawValue: 1 << 0)
|
|
static let multiline = Options(rawValue: 1 << 1)
|
|
static let dotMatchesLineSeparators = Options(rawValue: 1 << 2)
|
|
}
|
|
|
|
init(_ pattern: String, _ options: Options = []) throws {
|
|
var ops = NSRegularExpression.Options()
|
|
if options.contains(.caseInsensitive) { ops.insert(.caseInsensitive) }
|
|
if options.contains(.multiline) { ops.insert(.anchorsMatchLines) }
|
|
if options.contains(.dotMatchesLineSeparators) { ops.insert(.dotMatchesLineSeparators)}
|
|
|
|
self.regex = try NSRegularExpression(pattern: pattern, options: ops)
|
|
}
|
|
|
|
func isMatch(_ s: String) -> Bool {
|
|
let range = NSRange(s.startIndex..<s.endIndex, in: s)
|
|
return regex.firstMatch(in: s, options: [], range: range) != nil
|
|
}
|
|
|
|
func matches(in s: String) -> [Match] {
|
|
let range = NSRange(s.startIndex..<s.endIndex, in: s)
|
|
return matches(in: s, range: range)
|
|
}
|
|
|
|
func matches(in s: String, range: NSRange) -> [Match] {
|
|
let matches = regex.matches(in: s, options: [], range: range)
|
|
return matches.map { match in
|
|
let ranges = (0..<match.numberOfRanges)
|
|
.map { match.range(at: $0) }
|
|
.filter { $0.location != NSNotFound }
|
|
return Match(fullMatch: s[Range(match.range, in: s)!],
|
|
groups: ranges.dropFirst().map { s[Range($0, in: s)!] }
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Regex {
|
|
struct Match {
|
|
let fullMatch: Substring
|
|
let groups: [Substring]
|
|
}
|
|
}
|