@@ -96,8 +96,10 @@ defmodule Regex do
96
96
97
97
@ doc """
98
98
Runs the regular expression against the given string.
99
- It returns a list with all matches, `nil` if no match occurred, or `[]`
100
- if it matched, `/g` was specified, but nothing was captured.
99
+ It returns a list with all matches or `nil` if no match occurred.
100
+
101
+ When the option `:capture` is set to `:groups`, it will capture all
102
+ the groups in the regex.
101
103
102
104
## Examples
103
105
@@ -128,29 +130,23 @@ defmodule Regex do
128
130
end
129
131
130
132
@ doc """
131
- Returns the given captures as a keyword list or `nil` if no captures are found.
132
- Requires the regex to be compiled with the groups option.
133
+ Returns the given captures as a keyword list or `nil` if no captures
134
+ are found. Requires the regex to be compiled with the groups option.
133
135
134
136
## Examples
135
137
136
138
iex> Regex.captures(%r/c(?<foo>d)/g, "abcd")
137
139
[foo: "d"]
138
140
iex> Regex.captures(%r/a(?<foo>b)c(?<bar>d)/g, "abcd")
139
- [bar : "d ", foo : "b "]
141
+ [foo : "b ", bar : "d "]
140
142
iex> Regex.captures(%r/a(?<foo>b)c(?<bar>d)/g, "efgh")
141
143
nil
144
+
142
145
"""
143
146
def captures ( regex ( groups: groups ) = regex , string , options // [ ] ) do
144
- unless captures = Keyword . get ( options , :capture ) do
145
- captures = if groups do
146
- Enum . sort ( groups )
147
- else
148
- raise ArgumentError , message: "regex was not compiled with g"
149
- end
150
- options = Keyword . put ( options , :capture , captures )
151
- end
147
+ options = Keyword . put_new ( options , :capture , :groups )
152
148
results = run ( regex , string , options )
153
- if results , do: Enum . zip ( captures , results )
149
+ if results , do: Enum . zip ( groups , results )
154
150
end
155
151
156
152
@doc """
@@ -200,29 +196,42 @@ defmodule Regex do
200
196
end
201
197
202
198
@ doc """
203
- Same as run, but scans the target several times collecting all matches of
204
- the regular expression. A list is returned with each match. If the item in
205
- the list is a binary, it means there were no captures. If the item is another
206
- list, each element in this secondary list is a capture.
199
+ Same as run, but scans the target several times collecting all
200
+ matches of the regular expression. A list of lists is returned,
201
+ where each entry in the primary list represents a match and each
202
+ entry in the secondary list represents the captured contents.
203
+
204
+ The captured contents defaults to :all, which includes the whole
205
+ regex match and each capture.
206
+
207
+ When the option `:capture` is set to `:groups`, it will capture all
208
+ the groups in the regex.
207
209
208
210
## Examples
209
211
210
212
iex> Regex.scan(%r/c(d|e)/, "abcd abce")
211
- [["d"], ["e"]]
213
+ [["cd", " d"], ["ce", "e"]]
212
214
iex> Regex.scan(%r/c(?:d|e)/, "abcd abce")
213
- ["cd", "ce"]
215
+ [[ "cd"], [ "ce"] ]
214
216
iex> Regex.scan(%r/e/, "abcd")
215
217
[]
216
218
217
219
"""
218
220
def scan( regex, string , options // [ ] )
219
221
220
- def scan( regex( re_pattern: compiled) , string , options ) do
222
+ def scan( regex( re_pattern: compiled, groups: groups ) , string, options) do
221
223
return = Keyword.get( options, :return , return_for( string) )
222
- options = [ { :capture , :all , return } , :global ]
224
+
225
+ captures =
226
+ case Keyword.get( options, :capture , :all ) do
227
+ :groups -> groups || raise ArgumentError , message: "regex was not compiled with g"
228
+ others -> others
229
+ end
230
+
231
+ options = [ { :capture , captures , return } , :global ]
223
232
case :re . run ( string , compiled , options ) do
224
233
:nomatch -> [ ]
225
- { :match , results } -> flatten_result ( results )
234
+ { :match , results } -> results
226
235
end
227
236
end
228
237
@@ -330,15 +339,6 @@ defmodule Regex do
330
339
defp translate_options ( << ?g , t :: binary >> ) , do: [ :groups | translate_options ( t ) ]
331
340
defp translate_options ( << >> ) , do: [ ]
332
341
333
- defp flatten_result ( results ) do
334
- lc result inlist results do
335
- case result do
336
- [ t ] -> t
337
- [ _ | t ] -> t
338
- end
339
- end
340
- end
341
-
342
342
{ :ok , pattern } = :re . compile ( % B "\( \? <(?<G>[^>]*)>" )
343
343
@groups_pattern pattern
344
344
0 commit comments