-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathRegex.swift
68 lines (54 loc) · 2.12 KB
/
Regex.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import Foundation
private extension String {
var wholeRange: NSRange {
return NSRange(location: 0, length: characters.count)
}
//TODO: Use ObjectiveCBridgeable or wait until NSRegularExpression has a swifty API
var _ns: NSString {
return self as NSString
}
func substringWithRange(_ range: NSRange) -> String {
return self._ns.substring(with: range)
}
}
private extension NSTextCheckingResult {
var ranges: [NSRange] {
var ranges = [NSRange]()
for i in 0 ..< numberOfRanges {
ranges.append(range(at: i))
}
return ranges
}
}
public struct Match {
public let matchedString: String
public let captureGroups: [String]
public init(baseString string: String, checkingResult: NSTextCheckingResult) {
matchedString = string.substringWithRange(checkingResult.range)
captureGroups = checkingResult.ranges.dropFirst().map { range in
range.location == NSNotFound ? "" : string.substringWithRange(range)
}
}
}
public struct Regex {
public let pattern: String
public let options: NSRegularExpression.Options
fileprivate let matcher: NSRegularExpression
public init?(pattern: String, options: NSRegularExpression.Options = []) {
guard let matcher = try? NSRegularExpression(pattern: pattern, options: options) else {
return nil
}
self.matcher = matcher
self.pattern = pattern
self.options = options
}
public func match(_ string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange? = .none) -> Bool {
let range = range ?? string.wholeRange
return matcher.numberOfMatches(in: string, options: options, range: range) != 0
}
public func matches(_ string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange? = .none) -> [Match] {
let range = range ?? string.wholeRange
return matcher.matches(in: string, options: options, range: range).map { Match(baseString: string, checkingResult: $0)
}
}
}