Ramano
Ramano

Reputation: 625

Working with capture groups in Elixir

In the documentation I've not found the description of how to use capture groups in Elixir. How can I do that? Say, I want to extract a substring from a string and replace it with something else:

~r"\[tag1\](.+?)\[\/tag1\]"

How can I access the string in between ] [/?

Upvotes: 1

Views: 6254

Answers (2)

Drew2
Drew2

Reputation: 401

The docs do a good job at hiding it, but it's there: https://hexdocs.pm/elixir/1.0.5/Regex.html#replace/4

The replacement can be either a string or a function. The string is used as a replacement for every match and it allows specific captures to be accessed via \N or \g{N}, where N is the capture. In case \0 is used, the whole match is inserted.

Note: the \ in \N needs to be escaped so it will be \\N

Use Regex.replace/4 (or String.replace/4 when piping because the string is the first argument) to do this with one command.

You do not actually need to capture what is in between] [\ in the first place. You only need to match and replace it. This solution uses a "lookaround" which you can find more information on here: http://www.regular-expressions.info/lookaround.html

iex(1)> String.replace("[tag1]foo[/tag1]", ~r"\w+(?=\[)", "bar")               
"[tag1]bar[/tag1]"

Upvotes: 1

Dogbert
Dogbert

Reputation: 222278

Use Regex.run/3 for 1 match, Regex.scan/3 for all matches, or check out other functions in the Regex module.

iex(1)> regex = ~r"\[tag1\](.+?)\[\/tag1\]"
~r/\[tag1\](.+?)\[\/tag1\]/
iex(2)> [_, inner] = Regex.run(regex, "[tag1]bar[/tag1]")
["[tag1]bar[/tag1]", "bar"]
iex(3)> inner
"bar"
iex(4) Regex.scan(regex, "[tag1]bar[/tag1] [tag1]baz[/tag1]")
[["[tag1]bar[/tag1]", "bar"], ["[tag1]baz[/tag1]", "baz"]]

Upvotes: 5

Related Questions