Skip to content

Commit 0251f56

Browse files
josevalimJosé Valim
authored andcommitted
Merge pull request #2933 from Kabie/Regex.replace
Fix and enhance &Regex.replace/4 Signed-off-by: José Valim <[email protected]>
1 parent e4acc08 commit 0251f56

File tree

3 files changed

+16
-6
lines changed

3 files changed

+16
-6
lines changed

lib/elixir/lib/regex.ex

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,8 @@ defmodule Regex do
419419
420420
The replacement can be either a string or a function. The string
421421
is used as a replacement for every match and it allows specific
422-
captures to be accessed via `\N`, where `N` is the capture. In
423-
case `\0` is used, the whole match is inserted.
422+
captures to be accessed via `\N` or `\g{N}`, where `N` is the
423+
capture. In case `\0` is used, the whole match is inserted.
424424
425425
When the replacement is a function, the function may have arity
426426
N where each argument maps to a capture, with the first argument
@@ -479,6 +479,11 @@ defmodule Regex do
479479
defp precompile_replacement(""),
480480
do: []
481481

482+
defp precompile_replacement(<<?\\, ?g, ?{, rest :: binary>>) when byte_size(rest) > 0 do
483+
{ns, <<?}, rest :: binary>>} = pick_int(rest)
484+
[List.to_integer(ns) | precompile_replacement(rest)]
485+
end
486+
482487
defp precompile_replacement(<<?\\, x, rest :: binary>>) when x < ?0 or x > ?9 do
483488
case precompile_replacement(rest) do
484489
[head | t] when is_binary(head) ->
@@ -550,7 +555,7 @@ defmodule Regex do
550555
cond do
551556
is_binary(part) ->
552557
part
553-
part > tuple_size(indexes) ->
558+
part >= tuple_size(indexes) ->
554559
""
555560
true ->
556561
get_index(string, elem(indexes, part))

lib/elixir/lib/string.ex

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,13 +650,14 @@ defmodule String do
650650
iex> String.replace("a,b,c", ",", "-", global: false)
651651
"a-b,c"
652652
653-
The pattern can also be a regex. In those cases, one can give `\N`
654-
in the `replacement` string to access a specific capture in the regex:
653+
The pattern can also be a regex. In those cases, one can give `\N` or
654+
`\g{N}` in the `replacement` string to access a specific capture in the
655+
regex:
655656
656657
iex> String.replace("a,b,c", ~r/,(.)/, ",\\1\\1")
657658
"a,bb,cc"
658659
659-
Notice we had to escape the escape character `\`. By giving `&`,
660+
Notice we had to escape the escape character `\`. By giving `\0`,
660661
one can inject the whole matched pattern in the replacement string.
661662
662663
When strings are used as a pattern, a developer can also use the

lib/elixir/test/elixir/regex_test.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ defmodule RegexTest do
189189
assert Regex.replace(~r(b), "abc", "d") == "adc"
190190
assert Regex.replace(~r(b), "abc", "[\\0]") == "a[b]c"
191191
assert Regex.replace(~r[(b)], "abc", "[\\1]") == "a[b]c"
192+
assert Regex.replace(~r[(b)], "abc", "[\\2]") == "a[]c"
193+
assert Regex.replace(~r[(b)], "abc", "[\\3]") == "a[]c"
194+
assert Regex.replace(~r(b), "abc", "[\\g{0}]") == "a[b]c"
195+
assert Regex.replace(~r[(b)], "abc", "[\\g{1}]") == "a[b]c"
192196

193197
assert Regex.replace(~r(b), "abcbe", "d") == "adcde"
194198
assert Regex.replace(~r(b), "abcbe", "d", global: false) == "adcbe"

0 commit comments

Comments
 (0)