@@ -182,6 +182,91 @@ class Regex
182
182
@string .byte_slice(byte_end(0 ))
183
183
end
184
184
185
+ # Returns an array of unnamed capture groups.
186
+ #
187
+ # It is a difference from `to_a` that the result array does not contain the match for the entire `Regex` (`self[0]`).
188
+ #
189
+ # ```
190
+ # match = "Crystal".match(/(Cr)(?<name1>y)(st)(?<name2>al)/).not_nil!
191
+ # match.captures # => ["Cr", "st"]
192
+ #
193
+ # # When this regex has an optional group, result array may contain
194
+ # # a `nil` if this group is not matched.
195
+ # match = "Crystal".match(/(Cr)(stal)?/).not_nil!
196
+ # match.captures # => ["Cr", nil]
197
+ # ```
198
+ def captures
199
+ name_table = @regex .name_table
200
+
201
+ caps = [] of String ?
202
+ (1 ..size).each do |i |
203
+ caps << self [i]? unless name_table.has_key? i
204
+ end
205
+
206
+ caps
207
+ end
208
+
209
+ # Returns a hash of named capture groups.
210
+ #
211
+ # ```
212
+ # match = "Crystal".match(/(Cr)(?<name1>y)(st)(?<name2>al)/).not_nil!
213
+ # match.named_captures # => {"name1" => "y", "name2" => "al"}
214
+ #
215
+ # # When this regex has an optional group, result hash may contain
216
+ # # a `nil` if this group is not matched.
217
+ # match = "Crystal".match(/(?<name1>Cr)(?<name2>stal)?/).not_nil!
218
+ # match.named_captures # => {"name1" => "Cr", "name2" => nil}
219
+ # ```
220
+ def named_captures
221
+ name_table = @regex .name_table
222
+
223
+ caps = {} of String => String ?
224
+ (1 ..size).each do |i |
225
+ if name = name_table[i]?
226
+ caps[name] = self [i]?
227
+ end
228
+ end
229
+
230
+ caps
231
+ end
232
+
233
+ # Convert this match data into an array.
234
+ #
235
+ # ```
236
+ # match = "Crystal".match(/(Cr)(?<name1>y)(st)(?<name2>al)/).not_nil!
237
+ # match.to_a # => ["Crystal", "Cr", "y", "st", "al"]
238
+ #
239
+ # # When this regex has an optional group, result array may contain
240
+ # # a `nil` if this group is not matched.
241
+ # match = "Crystal".match(/(Cr)(?<name1>stal)?/).not_nil!
242
+ # match.to_a # => ["Cr", "Cr", nil]
243
+ # ```
244
+ def to_a
245
+ (0 ..size).map { |i | self [i]? }
246
+ end
247
+
248
+ # Convert this match data into a hash.
249
+ #
250
+ # ```
251
+ # match = "Crystal".match(/(Cr)(?<name1>y)(st)(?<name2>al)/).not_nil!
252
+ # match.to_h # => {0 => "Crystal", 1 => "Cr", "name1" => "y", 3 => "st", "name2" => "al"}
253
+ #
254
+ # # When this regex has an optional group, result array may contain
255
+ # # a `nil` if this group is not matched.
256
+ # match = "Crystal".match(/(Cr)(?<name1>stal)?/).not_nil!
257
+ # match.to_h # => {0 => "Cr", 1 => "Cr", "name1" => nil}
258
+ # ```
259
+ def to_h
260
+ name_table = @regex .name_table
261
+
262
+ hash = {} of (String | Int32 ) => String ?
263
+ (0 ..size).each do |i |
264
+ hash[name_table.fetch(i) { i }] = self [i]?
265
+ end
266
+
267
+ hash
268
+ end
269
+
185
270
def inspect (io : IO )
186
271
to_s(io)
187
272
end
0 commit comments