Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions lib/elixir/lib/regex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ defmodule Regex do
(the previous `r` option is deprecated in favor of `U`)

* `:export` (E) (since Elixir 1.19.3) - uses an exported pattern
which can be shared across nodes or through config, at the cost of a runtime
overhead every time to re-import it every time it is executed.
which can be shared across nodes or passed through config, at the cost of a runtime
overhead to re-import it every time it is executed.
This modifier only has an effect starting on Erlang/OTP 28, and it is ignored
on older versions (i.e. `~r/foo/E == ~r/foo/`). This is because patterns cannot
and do not need to be exported in order to be shared in these versions.
Expand Down Expand Up @@ -275,6 +275,35 @@ defmodule Regex do
regex
end

@doc """
Imports a `regex` that has been exported, otherwise returns the `regex` unchanged.

This means it will lose the ability to be sent across nodes or passed through config,
but will be faster since it won't need to be imported on the fly every time it is executed.

Exported regexes only exist on OTP 28, so this has no effect on older versions.

## Examples

Regex.import(~r/foo/E)
~r/foo/
Comment on lines +288 to +289
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Real doc test doesn't work because of ref comparison


Regex.import(~r/foo/)
~r/foo/

"""
@doc since: "1.20.0"
@spec import(t) :: t
def import(%Regex{re_pattern: re_pattern} = regex) do
case re_pattern do
{:re_exported_pattern, _, _, _, _} ->
%{regex | re_pattern: :re.import(re_pattern), opts: regex.opts -- [:export]}

_ ->
regex
end
end

@doc """
Returns the version of the underlying Regex engine.
"""
Expand Down
12 changes: 12 additions & 0 deletions lib/elixir/test/elixir/regex_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ defmodule RegexTest do
end
end

test "import/1" do
# no-op for non-exported regexes
regex = ~r/foo/
assert Regex.import(regex) == regex

imported = Regex.import(~r/foo/E)

assert imported.opts == []
assert "foo" =~ imported
assert {:re_pattern, _, _, _, _} = imported.re_pattern
end

test "opts/1" do
assert Regex.opts(Regex.compile!("foo", "i")) == [:caseless]
assert Regex.opts(Regex.compile!("foo", [:ucp])) == [:ucp]
Expand Down