11
11
12
12
@_implementationOnly import _RegexParser
13
13
14
- @available ( SwiftStdlib 5 . 7 , * )
15
- extension Regex where Output == AnyRegexOutput {
16
- /// Parses and compiles a regular expression, resulting in an existentially-typed capture list.
17
- ///
18
- /// - Parameter pattern: The regular expression.
19
- public init ( _ pattern: String ) throws {
20
- self . init ( ast: try parse ( pattern, . semantic, . traditional) )
21
- }
22
- }
23
-
24
- @available ( SwiftStdlib 5 . 7 , * )
25
- extension Regex {
26
- /// Parses and compiles a regular expression.
27
- ///
28
- /// - Parameter pattern: The regular expression.
29
- /// - Parameter as: The desired type for the output.
30
- public init (
31
- _ pattern: String ,
32
- as: Output . Type = Output . self
33
- ) throws {
34
- self . init ( ast: try parse ( pattern, . semantic, . traditional) )
35
- }
36
- }
37
-
38
- @available ( SwiftStdlib 5 . 7 , * )
39
- extension Regex . Match where Output == AnyRegexOutput {
40
- /// Accesses the whole match using the `.0` syntax.
41
- public subscript(
42
- dynamicMember keyPath: KeyPath < ( Substring , _doNotUse: ( ) ) , Substring >
43
- ) -> Substring {
44
- anyRegexOutput. input [ range]
45
- }
46
-
47
- /// Access a capture by name. Returns `nil` if there's no capture with that name.
48
- public subscript( name: String ) -> AnyRegexOutput . Element ? {
49
- anyRegexOutput. first {
50
- $0. name == name
51
- }
52
- }
53
- }
54
-
55
14
/// A type-erased regex output.
56
15
@available ( SwiftStdlib 5 . 7 , * )
57
16
public struct AnyRegexOutput {
@@ -90,7 +49,7 @@ extension AnyRegexOutput: RandomAccessCollection {
90
49
public struct Element {
91
50
internal let representation : ElementRepresentation
92
51
internal let input : String
93
-
52
+
94
53
/// The range over which a value was captured. `nil` for no-capture.
95
54
public var range : Range < String . Index > ? {
96
55
representation. bounds
@@ -160,19 +119,62 @@ extension AnyRegexOutput {
160
119
161
120
@available ( SwiftStdlib 5 . 7 , * )
162
121
extension Regex . Match where Output == AnyRegexOutput {
163
- /// Creates a type-erased regex match from an existing match.
122
+ /// Accesses the whole match using the `.0` syntax.
123
+ public subscript(
124
+ dynamicMember keyPath: KeyPath < ( Substring , _doNotUse: ( ) ) , Substring >
125
+ ) -> Substring {
126
+ anyRegexOutput. input [ range]
127
+ }
128
+
129
+ /// Access a capture by name. Returns `nil` if there's no capture with that name.
130
+ public subscript( name: String ) -> AnyRegexOutput . Element ? {
131
+ anyRegexOutput. first {
132
+ $0. name == name
133
+ }
134
+ }
135
+ }
136
+
137
+ // MARK: - Run-time regex creation and queries
138
+
139
+ @available ( SwiftStdlib 5 . 7 , * )
140
+ extension Regex where Output == AnyRegexOutput {
141
+ /// Parses and compiles a regular expression, resulting in an existentially-typed capture list.
164
142
///
165
- /// Use this initializer to fit a regex match with strongly typed captures into the
166
- /// use site of a dynamic regex match, like one that was created from a string.
167
- public init < Output> ( _ match: Regex < Output > . Match ) {
168
- self . init (
169
- anyRegexOutput: match. anyRegexOutput,
170
- range: match. range,
171
- value: match. value
172
- )
143
+ /// - Parameter pattern: The regular expression.
144
+ public init ( _ pattern: String ) throws {
145
+ self . init ( ast: try parse ( pattern, . semantic, . traditional) )
146
+ }
147
+ }
148
+
149
+ @available ( SwiftStdlib 5 . 7 , * )
150
+ extension Regex {
151
+ /// Parses and compiles a regular expression.
152
+ ///
153
+ /// - Parameter pattern: The regular expression.
154
+ /// - Parameter as: The desired type for the output.
155
+ public init (
156
+ _ pattern: String ,
157
+ as: Output . Type = Output . self
158
+ ) throws {
159
+ self . init ( ast: try parse ( pattern, . semantic, . traditional) )
160
+ }
161
+
162
+ /// Produces a regex that matches `verbatim` exactly, as though every
163
+ /// metacharacter in it was escaped.
164
+ public init ( verbatim: String ) {
165
+ self . init ( node: . quotedLiteral( verbatim) )
166
+ }
167
+
168
+ /// Returns whether a named-capture with `name` exists
169
+ public func contains( captureNamed name: String ) -> Bool {
170
+ program. tree. root. _captureList. captures. contains ( where: {
171
+ $0. name == name
172
+ } )
173
173
}
174
174
}
175
175
176
+ // MARK: - Converting to/from ARO
177
+
176
178
@available ( SwiftStdlib 5 . 7 , * )
177
179
extension Regex where Output == AnyRegexOutput {
178
180
/// Creates a type-erased regex from an existing regex.
@@ -184,6 +186,21 @@ extension Regex where Output == AnyRegexOutput {
184
186
}
185
187
}
186
188
189
+ @available ( SwiftStdlib 5 . 7 , * )
190
+ extension Regex . Match where Output == AnyRegexOutput {
191
+ /// Creates a type-erased regex match from an existing match.
192
+ ///
193
+ /// Use this initializer to fit a regex match with strongly typed captures into the
194
+ /// use site of a dynamic regex match, like one that was created from a string.
195
+ public init < Output> ( _ match: Regex < Output > . Match ) {
196
+ self . init (
197
+ anyRegexOutput: match. anyRegexOutput,
198
+ range: match. range,
199
+ value: match. value
200
+ )
201
+ }
202
+ }
203
+
187
204
@available ( SwiftStdlib 5 . 7 , * )
188
205
extension Regex {
189
206
/// Creates a strongly-typed regex from a dynamic regex, i.e. one created
@@ -192,21 +209,19 @@ extension Regex {
192
209
/// Use this initializer to create a strongly typed regex from
193
210
/// one that was created from a string. Returns `nil` if the types
194
211
/// don't match.
195
- public init ? ( _ dynamic: Regex < AnyRegexOutput > ) {
212
+ public init ? (
213
+ _ dynamic: Regex < AnyRegexOutput > ,
214
+ as: Output . Type = Output . self
215
+ ) {
196
216
self . init ( node: dynamic. root)
197
217
guard self . _verifyType ( ) else {
198
218
return nil
199
219
}
200
220
}
201
-
202
- /// Returns whether a named-capture with `name` exists
203
- public func contains( captureNamed name: String ) -> Bool {
204
- program. tree. root. _captureList. captures. contains ( where: {
205
- $0. name == name
206
- } )
207
- }
208
221
}
209
222
223
+ // MARK: - Internals
224
+
210
225
@available ( SwiftStdlib 5 . 7 , * )
211
226
extension AnyRegexOutput {
212
227
/// The underlying representation of the element of a type-erased regex
@@ -251,12 +266,3 @@ extension AnyRegexOutput.ElementRepresentation {
251
266
)
252
267
}
253
268
}
254
-
255
- @available ( SwiftStdlib 5 . 7 , * )
256
- extension Regex {
257
- /// Produces a regex that matches `verbatim` exactly, as though every
258
- /// metacharacter in it was escaped.
259
- public init ( verbatim: String ) {
260
- self . init ( node: . quotedLiteral( verbatim) )
261
- }
262
- }
0 commit comments